Print this page
3245 in.ndp daemon should not be session leader
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/cmd-inet/usr.lib/in.ndpd/main.c
+++ new/usr/src/cmd/cmd-inet/usr.lib/in.ndpd/main.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 *
21 21 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
22 22 */
23 23
24 24 #include "defs.h"
25 25 #include "tables.h"
26 26 #include <fcntl.h>
27 27 #include <sys/un.h>
28 28
29 29 static void initlog(void);
30 30 static void run_timeouts(void);
31 31
32 32 static void advertise(struct sockaddr_in6 *sin6, struct phyint *pi,
33 33 boolean_t no_prefixes);
34 34 static void solicit(struct sockaddr_in6 *sin6, struct phyint *pi);
35 35 static void initifs(boolean_t first);
36 36 static void check_if_removed(struct phyint *pi);
37 37 static void loopback_ra_enqueue(struct phyint *pi,
38 38 struct nd_router_advert *ra, int len);
39 39 static void loopback_ra_dequeue(void);
40 40 static void check_daemonize(void);
41 41
42 42 struct in6_addr all_nodes_mcast = { { 0xff, 0x2, 0x0, 0x0,
43 43 0x0, 0x0, 0x0, 0x0,
44 44 0x0, 0x0, 0x0, 0x0,
45 45 0x0, 0x0, 0x0, 0x1 } };
46 46
47 47 struct in6_addr all_routers_mcast = { { 0xff, 0x2, 0x0, 0x0,
48 48 0x0, 0x0, 0x0, 0x0,
49 49 0x0, 0x0, 0x0, 0x0,
50 50 0x0, 0x0, 0x0, 0x2 } };
51 51
52 52 static struct sockaddr_in6 v6allnodes = { AF_INET6, 0, 0,
53 53 { 0xff, 0x2, 0x0, 0x0,
54 54 0x0, 0x0, 0x0, 0x0,
55 55 0x0, 0x0, 0x0, 0x0,
56 56 0x0, 0x0, 0x0, 0x1 } };
57 57
58 58 static struct sockaddr_in6 v6allrouters = { AF_INET6, 0, 0,
59 59 { 0xff, 0x2, 0x0, 0x0,
60 60 0x0, 0x0, 0x0, 0x0,
61 61 0x0, 0x0, 0x0, 0x0,
62 62 0x0, 0x0, 0x0, 0x2 } };
63 63
64 64 static char **argv0; /* Saved for re-exec on SIGHUP */
65 65
66 66 static uint64_t packet[(IP_MAXPACKET + 1)/8];
67 67
68 68 static int show_ifs = 0;
69 69 static boolean_t already_daemonized = _B_FALSE;
70 70 int debug = 0;
71 71 int no_loopback = 0; /* Do not send RA packets to ourselves */
72 72
73 73 /*
74 74 * Size of routing socket message used by in.ndpd which includes the header,
75 75 * space for the RTA_DST, RTA_GATEWAY and RTA_NETMASK (each a sockaddr_in6)
76 76 * plus space for the RTA_IFP (a sockaddr_dl).
77 77 */
78 78 #define NDP_RTM_MSGLEN sizeof (struct rt_msghdr) + \
79 79 sizeof (struct sockaddr_in6) + \
80 80 sizeof (struct sockaddr_in6) + \
81 81 sizeof (struct sockaddr_in6) + \
82 82 sizeof (struct sockaddr_dl)
83 83
84 84 /*
85 85 * These are referenced externally in tables.c in order to fill in the
86 86 * dynamic portions of the routing socket message and then to send the message
87 87 * itself.
88 88 */
89 89 int rtsock = -1; /* Routing socket */
90 90 struct rt_msghdr *rt_msg; /* Routing socket message */
91 91 struct sockaddr_in6 *rta_gateway; /* RTA_GATEWAY sockaddr */
92 92 struct sockaddr_dl *rta_ifp; /* RTA_IFP sockaddr */
93 93
94 94 /*
95 95 * These sockets are used internally in this file.
96 96 */
97 97 static int mibsock = -1; /* mib request socket */
98 98 static int cmdsock = -1; /* command socket */
99 99
100 100 static int ndpd_setup_cmd_listener(void);
101 101 static void ndpd_cmd_handler(int);
102 102 static int ndpd_process_cmd(int, ipadm_ndpd_msg_t *);
103 103 static int ndpd_send_error(int, int);
104 104 static int ndpd_set_autoconf(const char *, boolean_t);
105 105 static int ndpd_create_addrs(const char *, struct sockaddr_in6, int,
106 106 boolean_t, boolean_t, char *);
107 107 static int ndpd_delete_addrs(const char *);
108 108 static int phyint_check_ipadm_intfid(struct phyint *);
109 109
110 110 /*
111 111 * Return the current time in milliseconds truncated to
112 112 * fit in an integer.
113 113 */
114 114 uint_t
115 115 getcurrenttime(void)
116 116 {
117 117 struct timeval tp;
118 118
119 119 if (gettimeofday(&tp, NULL) < 0) {
120 120 logperror("getcurrenttime: gettimeofday failed");
121 121 exit(1);
122 122 }
123 123 return (tp.tv_sec * 1000 + tp.tv_usec / 1000);
124 124 }
125 125
126 126 /*
127 127 * Output a preformated packet from the packet[] buffer.
128 128 */
129 129 static void
130 130 sendpacket(struct sockaddr_in6 *sin6, int sock, int size, int flags)
131 131 {
132 132 int cc;
133 133 char abuf[INET6_ADDRSTRLEN];
134 134
135 135 cc = sendto(sock, (char *)packet, size, flags,
136 136 (struct sockaddr *)sin6, sizeof (*sin6));
137 137 if (cc < 0 || cc != size) {
138 138 if (cc < 0) {
139 139 logperror("sendpacket: sendto");
140 140 }
141 141 logmsg(LOG_ERR, "sendpacket: wrote %s %d chars, ret=%d\n",
142 142 inet_ntop(sin6->sin6_family,
143 143 (void *)&sin6->sin6_addr,
144 144 abuf, sizeof (abuf)),
145 145 size, cc);
146 146 }
147 147 }
148 148
149 149 /*
150 150 * If possible, place an ND_OPT_SOURCE_LINKADDR option at `optp'.
151 151 * Return the number of bytes placed in the option.
152 152 */
153 153 static uint_t
154 154 add_opt_lla(struct phyint *pi, struct nd_opt_lla *optp)
155 155 {
156 156 uint_t optlen;
157 157 uint_t hwaddrlen;
158 158 struct lifreq lifr;
159 159
160 160 /* If this phyint doesn't have a link-layer address, bail */
161 161 if (phyint_get_lla(pi, &lifr) == -1)
162 162 return (0);
163 163
164 164 hwaddrlen = lifr.lifr_nd.lnr_hdw_len;
165 165 /* roundup to multiple of 8 and make padding zero */
166 166 optlen = ((sizeof (struct nd_opt_hdr) + hwaddrlen + 7) / 8) * 8;
167 167 bzero(optp, optlen);
168 168 optp->nd_opt_lla_type = ND_OPT_SOURCE_LINKADDR;
169 169 optp->nd_opt_lla_len = optlen / 8;
170 170 bcopy(lifr.lifr_nd.lnr_hdw_addr, optp->nd_opt_lla_hdw_addr, hwaddrlen);
171 171
172 172 return (optlen);
173 173 }
174 174
175 175 /* Send a Router Solicitation */
176 176 static void
177 177 solicit(struct sockaddr_in6 *sin6, struct phyint *pi)
178 178 {
179 179 int packetlen = 0;
180 180 struct nd_router_solicit *rs = (struct nd_router_solicit *)packet;
181 181 char *pptr = (char *)packet;
182 182
183 183 rs->nd_rs_type = ND_ROUTER_SOLICIT;
184 184 rs->nd_rs_code = 0;
185 185 rs->nd_rs_cksum = htons(0);
186 186 rs->nd_rs_reserved = htonl(0);
187 187
188 188 packetlen += sizeof (*rs);
189 189 pptr += sizeof (*rs);
190 190
191 191 /* add options */
192 192 packetlen += add_opt_lla(pi, (struct nd_opt_lla *)pptr);
193 193
194 194 if (debug & D_PKTOUT) {
195 195 print_route_sol("Sending solicitation to ", pi, rs, packetlen,
196 196 sin6);
197 197 }
198 198 sendpacket(sin6, pi->pi_sock, packetlen, 0);
199 199 }
200 200
201 201 /*
202 202 * Send a (set of) Router Advertisements and feed them back to ourselves
203 203 * for processing. Unless no_prefixes is set all prefixes are included.
204 204 * If there are too many prefix options to fit in one packet multiple
205 205 * packets will be sent - each containing a subset of the prefix options.
206 206 */
207 207 static void
208 208 advertise(struct sockaddr_in6 *sin6, struct phyint *pi, boolean_t no_prefixes)
209 209 {
210 210 struct nd_opt_prefix_info *po;
211 211 char *pptr = (char *)packet;
212 212 struct nd_router_advert *ra;
213 213 struct adv_prefix *adv_pr;
214 214 int packetlen = 0;
215 215
216 216 ra = (struct nd_router_advert *)pptr;
217 217 ra->nd_ra_type = ND_ROUTER_ADVERT;
218 218 ra->nd_ra_code = 0;
219 219 ra->nd_ra_cksum = htons(0);
220 220 ra->nd_ra_curhoplimit = pi->pi_AdvCurHopLimit;
221 221 ra->nd_ra_flags_reserved = 0;
222 222 if (pi->pi_AdvManagedFlag)
223 223 ra->nd_ra_flags_reserved |= ND_RA_FLAG_MANAGED;
224 224 if (pi->pi_AdvOtherConfigFlag)
225 225 ra->nd_ra_flags_reserved |= ND_RA_FLAG_OTHER;
226 226
227 227 if (pi->pi_adv_state == FINAL_ADV)
228 228 ra->nd_ra_router_lifetime = htons(0);
229 229 else
230 230 ra->nd_ra_router_lifetime = htons(pi->pi_AdvDefaultLifetime);
231 231 ra->nd_ra_reachable = htonl(pi->pi_AdvReachableTime);
232 232 ra->nd_ra_retransmit = htonl(pi->pi_AdvRetransTimer);
233 233
234 234 packetlen = sizeof (*ra);
235 235 pptr += sizeof (*ra);
236 236
237 237 if (pi->pi_adv_state == FINAL_ADV) {
238 238 if (debug & D_PKTOUT) {
239 239 print_route_adv("Sending advert (FINAL) to ", pi,
240 240 ra, packetlen, sin6);
241 241 }
242 242 sendpacket(sin6, pi->pi_sock, packetlen, 0);
243 243 /* Feed packet back in for router operation */
244 244 loopback_ra_enqueue(pi, ra, packetlen);
245 245 return;
246 246 }
247 247
248 248 /* add options */
249 249 packetlen += add_opt_lla(pi, (struct nd_opt_lla *)pptr);
250 250 pptr = (char *)packet + packetlen;
251 251
252 252 if (pi->pi_AdvLinkMTU != 0) {
253 253 struct nd_opt_mtu *mo = (struct nd_opt_mtu *)pptr;
254 254
255 255 mo->nd_opt_mtu_type = ND_OPT_MTU;
256 256 mo->nd_opt_mtu_len = sizeof (struct nd_opt_mtu) / 8;
257 257 mo->nd_opt_mtu_reserved = 0;
258 258 mo->nd_opt_mtu_mtu = htonl(pi->pi_AdvLinkMTU);
259 259
260 260 packetlen += sizeof (struct nd_opt_mtu);
261 261 pptr += sizeof (struct nd_opt_mtu);
262 262 }
263 263
264 264 if (no_prefixes) {
265 265 if (debug & D_PKTOUT) {
266 266 print_route_adv("Sending advert to ", pi,
267 267 ra, packetlen, sin6);
268 268 }
269 269 sendpacket(sin6, pi->pi_sock, packetlen, 0);
270 270 /* Feed packet back in for router operation */
271 271 loopback_ra_enqueue(pi, ra, packetlen);
272 272 return;
273 273 }
274 274
275 275 po = (struct nd_opt_prefix_info *)pptr;
276 276 for (adv_pr = pi->pi_adv_prefix_list; adv_pr != NULL;
277 277 adv_pr = adv_pr->adv_pr_next) {
278 278 if (!adv_pr->adv_pr_AdvOnLinkFlag &&
279 279 !adv_pr->adv_pr_AdvAutonomousFlag) {
280 280 continue;
281 281 }
282 282
283 283 /*
284 284 * If the prefix doesn't fit in packet send
285 285 * what we have so far and start with new packet.
286 286 */
287 287 if (packetlen + sizeof (*po) >
288 288 pi->pi_LinkMTU - sizeof (struct ip6_hdr)) {
289 289 if (debug & D_PKTOUT) {
290 290 print_route_adv("Sending advert "
291 291 "(FRAG) to ",
292 292 pi, ra, packetlen, sin6);
293 293 }
294 294 sendpacket(sin6, pi->pi_sock, packetlen, 0);
295 295 /* Feed packet back in for router operation */
296 296 loopback_ra_enqueue(pi, ra, packetlen);
297 297 packetlen = sizeof (*ra);
298 298 pptr = (char *)packet + sizeof (*ra);
299 299 po = (struct nd_opt_prefix_info *)pptr;
300 300 }
301 301 po->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
302 302 po->nd_opt_pi_len = sizeof (*po)/8;
303 303 po->nd_opt_pi_flags_reserved = 0;
304 304 if (adv_pr->adv_pr_AdvOnLinkFlag) {
305 305 po->nd_opt_pi_flags_reserved |=
306 306 ND_OPT_PI_FLAG_ONLINK;
307 307 }
308 308 if (adv_pr->adv_pr_AdvAutonomousFlag) {
309 309 po->nd_opt_pi_flags_reserved |=
310 310 ND_OPT_PI_FLAG_AUTO;
311 311 }
312 312 po->nd_opt_pi_prefix_len = adv_pr->adv_pr_prefix_len;
313 313 /*
314 314 * If both Adv*Expiration and Adv*Lifetime are
315 315 * set we prefer the former and make the lifetime
316 316 * decrement in real time.
317 317 */
318 318 if (adv_pr->adv_pr_AdvValidRealTime) {
319 319 po->nd_opt_pi_valid_time =
320 320 htonl(adv_pr->adv_pr_AdvValidExpiration);
321 321 } else {
322 322 po->nd_opt_pi_valid_time =
323 323 htonl(adv_pr->adv_pr_AdvValidLifetime);
324 324 }
325 325 if (adv_pr->adv_pr_AdvPreferredRealTime) {
326 326 po->nd_opt_pi_preferred_time =
327 327 htonl(adv_pr->adv_pr_AdvPreferredExpiration);
328 328 } else {
329 329 po->nd_opt_pi_preferred_time =
330 330 htonl(adv_pr->adv_pr_AdvPreferredLifetime);
331 331 }
332 332 po->nd_opt_pi_reserved2 = htonl(0);
333 333 po->nd_opt_pi_prefix = adv_pr->adv_pr_prefix;
334 334
335 335 po++;
336 336 packetlen += sizeof (*po);
337 337 }
338 338 if (debug & D_PKTOUT) {
339 339 print_route_adv("Sending advert to ", pi,
340 340 ra, packetlen, sin6);
341 341 }
342 342 sendpacket(sin6, pi->pi_sock, packetlen, 0);
343 343 /* Feed packet back in for router operation */
344 344 loopback_ra_enqueue(pi, ra, packetlen);
345 345 }
346 346
347 347 /* Poll support */
348 348 static int pollfd_num = 0; /* Allocated and initialized */
349 349 static struct pollfd *pollfds = NULL;
350 350
351 351 /*
352 352 * Add fd to the set being polled. Returns 0 if ok; -1 if failed.
353 353 */
354 354 int
355 355 poll_add(int fd)
356 356 {
357 357 int i;
358 358 int new_num;
359 359 struct pollfd *newfds;
360 360
361 361 /* Check if already present */
362 362 for (i = 0; i < pollfd_num; i++) {
363 363 if (pollfds[i].fd == fd)
364 364 return (0);
365 365 }
366 366 /* Check for empty spot already present */
367 367 for (i = 0; i < pollfd_num; i++) {
368 368 if (pollfds[i].fd == -1) {
369 369 pollfds[i].fd = fd;
370 370 return (0);
371 371 }
372 372 }
373 373
374 374 /* Allocate space for 32 more fds and initialize to -1 */
375 375 new_num = pollfd_num + 32;
376 376 newfds = realloc(pollfds, new_num * sizeof (struct pollfd));
377 377 if (newfds == NULL) {
378 378 logperror("realloc");
379 379 return (-1);
380 380 }
381 381
382 382 newfds[pollfd_num].fd = fd;
383 383 newfds[pollfd_num++].events = POLLIN;
384 384
385 385 for (i = pollfd_num; i < new_num; i++) {
386 386 newfds[i].fd = -1;
387 387 newfds[i].events = POLLIN;
388 388 }
389 389 pollfd_num = new_num;
390 390 pollfds = newfds;
391 391 return (0);
392 392 }
393 393
394 394 /*
395 395 * Remove fd from the set being polled. Returns 0 if ok; -1 if failed.
396 396 */
397 397 int
398 398 poll_remove(int fd)
399 399 {
400 400 int i;
401 401
402 402 /* Check if already present */
403 403 for (i = 0; i < pollfd_num; i++) {
404 404 if (pollfds[i].fd == fd) {
405 405 pollfds[i].fd = -1;
406 406 return (0);
407 407 }
408 408 }
409 409 return (-1);
410 410 }
411 411
412 412 /*
413 413 * Extract information about the ifname (either a physical interface and
414 414 * the ":0" logical interface or just a logical interface).
415 415 * If the interface (still) exists in kernel set pr_in_use
416 416 * for caller to be able to detect interfaces that are removed.
417 417 * Starts sending advertisements/solicitations when new physical interfaces
418 418 * are detected.
419 419 */
420 420 static void
421 421 if_process(int s, char *ifname, boolean_t first)
422 422 {
423 423 struct lifreq lifr;
424 424 struct phyint *pi;
425 425 struct prefix *pr;
426 426 char *cp;
427 427 char phyintname[LIFNAMSIZ + 1];
428 428
429 429 if (debug & D_IFSCAN)
430 430 logmsg(LOG_DEBUG, "if_process(%s)\n", ifname);
431 431
432 432 (void) strncpy(lifr.lifr_name, ifname, sizeof (lifr.lifr_name));
433 433 lifr.lifr_name[sizeof (lifr.lifr_name) - 1] = '\0';
434 434 if (ioctl(s, SIOCGLIFFLAGS, (char *)&lifr) < 0) {
435 435 if (errno == ENXIO) {
436 436 /*
437 437 * Interface has disappeared
438 438 */
439 439 return;
440 440 }
441 441 logperror("if_process: ioctl (get interface flags)");
442 442 return;
443 443 }
444 444
445 445 /*
446 446 * Ignore loopback, point-to-multipoint and VRRP interfaces.
447 447 * The IP addresses over VRRP interfaces cannot be auto-configured.
448 448 * Point-to-point interfaces always have IFF_MULTICAST set.
449 449 */
450 450 if (!(lifr.lifr_flags & IFF_MULTICAST) ||
451 451 (lifr.lifr_flags & (IFF_LOOPBACK|IFF_VRRP))) {
452 452 return;
453 453 }
454 454
455 455 if (!(lifr.lifr_flags & IFF_IPV6))
456 456 return;
457 457
458 458 (void) strncpy(phyintname, ifname, sizeof (phyintname));
459 459 phyintname[sizeof (phyintname) - 1] = '\0';
460 460 if ((cp = strchr(phyintname, IF_SEPARATOR)) != NULL) {
461 461 *cp = '\0';
462 462 }
463 463
464 464 pi = phyint_lookup(phyintname);
465 465 if (pi == NULL) {
466 466 pi = phyint_create(phyintname);
467 467 if (pi == NULL) {
468 468 logmsg(LOG_ERR, "if_process: out of memory\n");
469 469 return;
470 470 }
471 471 /*
472 472 * if in.ndpd is restarted, check with ipmgmtd if there is any
473 473 * interface id to be configured for this interface.
474 474 */
475 475 if (first) {
476 476 if (phyint_check_ipadm_intfid(pi) == -1)
477 477 logmsg(LOG_ERR, "Could not get ipadm info\n");
478 478 }
479 479 } else {
480 480 /*
481 481 * if the phyint already exists, synchronize it with
482 482 * the kernel state. For a newly created phyint, phyint_create
483 483 * calls phyint_init_from_k().
484 484 */
485 485 (void) phyint_init_from_k(pi);
486 486 }
487 487 if (pi->pi_sock == -1 && !(pi->pi_kernel_state & PI_PRESENT)) {
488 488 /* Interface is not yet present */
489 489 if (debug & D_PHYINT) {
490 490 logmsg(LOG_DEBUG, "if_process: interface not yet "
491 491 "present %s\n", pi->pi_name);
492 492 }
493 493 return;
494 494 }
495 495
496 496 if (pi->pi_sock != -1) {
497 497 if (poll_add(pi->pi_sock) == -1) {
498 498 /*
499 499 * reset state.
500 500 */
501 501 phyint_cleanup(pi);
502 502 }
503 503 }
504 504
505 505 /*
506 506 * Check if IFF_ROUTER has been turned off in kernel in which
507 507 * case we have to turn off AdvSendAdvertisements.
508 508 * The kernel will automatically turn off IFF_ROUTER if
509 509 * ip6_forwarding is turned off.
510 510 * Note that we do not switch back should IFF_ROUTER be turned on.
511 511 */
512 512 if (!first &&
513 513 pi->pi_AdvSendAdvertisements && !(pi->pi_flags & IFF_ROUTER)) {
514 514 logmsg(LOG_INFO, "No longer a router on %s\n", pi->pi_name);
515 515 check_to_advertise(pi, START_FINAL_ADV);
516 516
517 517 pi->pi_AdvSendAdvertisements = 0;
518 518 pi->pi_sol_state = NO_SOLICIT;
519 519 }
520 520
521 521 /*
522 522 * Send advertisments and solicitation only if the interface is
523 523 * present in the kernel.
524 524 */
525 525 if (pi->pi_kernel_state & PI_PRESENT) {
526 526
527 527 if (pi->pi_AdvSendAdvertisements) {
528 528 if (pi->pi_adv_state == NO_ADV)
529 529 check_to_advertise(pi, START_INIT_ADV);
530 530 } else {
531 531 if (pi->pi_sol_state == NO_SOLICIT)
532 532 check_to_solicit(pi, START_INIT_SOLICIT);
533 533 }
534 534 }
535 535
536 536 /*
537 537 * Track static kernel prefixes to prevent in.ndpd from clobbering
538 538 * them by creating a struct prefix for each prefix detected in the
539 539 * kernel.
540 540 */
541 541 pr = prefix_lookup_name(pi, ifname);
542 542 if (pr == NULL) {
543 543 pr = prefix_create_name(pi, ifname);
544 544 if (pr == NULL) {
545 545 logmsg(LOG_ERR, "if_process: out of memory\n");
546 546 return;
547 547 }
548 548 if (prefix_init_from_k(pr) == -1) {
549 549 prefix_delete(pr);
550 550 return;
551 551 }
552 552 }
553 553 /* Detect prefixes which are removed */
554 554 if (pr->pr_kernel_state != 0)
555 555 pr->pr_in_use = _B_TRUE;
556 556
557 557 if ((lifr.lifr_flags & IFF_DUPLICATE) &&
558 558 !(lifr.lifr_flags & IFF_DHCPRUNNING) &&
559 559 (pr->pr_flags & IFF_TEMPORARY)) {
560 560 in6_addr_t *token;
561 561 int i;
562 562 char abuf[INET6_ADDRSTRLEN];
563 563
564 564 if (++pr->pr_attempts >= MAX_DAD_FAILURES) {
565 565 logmsg(LOG_ERR, "%s: token %s is duplicate after %d "
566 566 "attempts; disabling temporary addresses on %s",
567 567 pr->pr_name, inet_ntop(AF_INET6,
568 568 (void *)&pi->pi_tmp_token, abuf, sizeof (abuf)),
569 569 pr->pr_attempts, pi->pi_name);
570 570 pi->pi_TmpAddrsEnabled = 0;
571 571 tmptoken_delete(pi);
572 572 prefix_delete(pr);
573 573 return;
574 574 }
575 575 logmsg(LOG_WARNING, "%s: token %s is duplicate; trying again",
576 576 pr->pr_name, inet_ntop(AF_INET6, (void *)&pi->pi_tmp_token,
577 577 abuf, sizeof (abuf)));
578 578 if (!tmptoken_create(pi)) {
579 579 prefix_delete(pr);
580 580 return;
581 581 }
582 582 token = &pi->pi_tmp_token;
583 583 for (i = 0; i < 16; i++) {
584 584 /*
585 585 * prefix_create ensures that pr_prefix has all-zero
586 586 * bits after prefixlen.
587 587 */
588 588 pr->pr_address.s6_addr[i] = pr->pr_prefix.s6_addr[i] |
589 589 token->s6_addr[i];
590 590 }
591 591 if (prefix_lookup_addr_match(pr) != NULL) {
592 592 prefix_delete(pr);
593 593 return;
594 594 }
595 595 pr->pr_CreateTime = getcurrenttime() / MILLISEC;
596 596 /*
597 597 * We've got a new token. Clearing PR_AUTO causes
598 598 * prefix_update_k to bring the interface up and set the
599 599 * address.
600 600 */
601 601 pr->pr_kernel_state &= ~PR_AUTO;
602 602 prefix_update_k(pr);
603 603 }
604 604 }
605 605
606 606 static int ifsock = -1;
607 607
608 608 /*
609 609 * Scan all interfaces to detect changes as well as new and deleted intefaces
610 610 * 'first' is set for the initial call only. Do not effect anything.
611 611 */
612 612 static void
613 613 initifs(boolean_t first)
614 614 {
615 615 char *buf;
616 616 int bufsize;
617 617 int numifs;
618 618 int n;
619 619 struct lifnum lifn;
620 620 struct lifconf lifc;
621 621 struct lifreq *lifr;
622 622 struct phyint *pi;
623 623 struct phyint *next_pi;
624 624 struct prefix *pr;
625 625
626 626 if (debug & D_IFSCAN)
627 627 logmsg(LOG_DEBUG, "Reading interface configuration\n");
628 628 if (ifsock < 0) {
629 629 ifsock = socket(AF_INET6, SOCK_DGRAM, 0);
630 630 if (ifsock < 0) {
631 631 logperror("initifs: socket");
632 632 return;
633 633 }
634 634 }
635 635 lifn.lifn_family = AF_INET6;
636 636 lifn.lifn_flags = LIFC_NOXMIT | LIFC_TEMPORARY;
637 637 if (ioctl(ifsock, SIOCGLIFNUM, (char *)&lifn) < 0) {
638 638 logperror("initifs: ioctl (get interface numbers)");
639 639 return;
640 640 }
641 641 numifs = lifn.lifn_count;
642 642 bufsize = numifs * sizeof (struct lifreq);
643 643
644 644 buf = (char *)malloc(bufsize);
645 645 if (buf == NULL) {
646 646 logmsg(LOG_ERR, "initifs: out of memory\n");
647 647 return;
648 648 }
649 649
650 650 /*
651 651 * Mark the interfaces so that we can find phyints and prefixes
652 652 * which have disappeared from the kernel.
653 653 * if_process will set pr_in_use when it finds the interface
654 654 * in the kernel.
655 655 */
656 656 for (pi = phyints; pi != NULL; pi = pi->pi_next) {
657 657 /*
658 658 * Before re-examining the state of the interfaces,
659 659 * PI_PRESENT should be cleared from pi_kernel_state.
660 660 */
661 661 pi->pi_kernel_state &= ~PI_PRESENT;
662 662 for (pr = pi->pi_prefix_list; pr != NULL; pr = pr->pr_next) {
663 663 pr->pr_in_use = _B_FALSE;
664 664 }
665 665 }
666 666
667 667 lifc.lifc_family = AF_INET6;
668 668 lifc.lifc_flags = LIFC_NOXMIT | LIFC_TEMPORARY;
669 669 lifc.lifc_len = bufsize;
670 670 lifc.lifc_buf = buf;
671 671
672 672 if (ioctl(ifsock, SIOCGLIFCONF, (char *)&lifc) < 0) {
673 673 logperror("initifs: ioctl (get interface configuration)");
674 674 free(buf);
675 675 return;
676 676 }
677 677
678 678 lifr = (struct lifreq *)lifc.lifc_req;
679 679 for (n = lifc.lifc_len / sizeof (struct lifreq); n > 0; n--, lifr++)
680 680 if_process(ifsock, lifr->lifr_name, first);
681 681 free(buf);
682 682
683 683 /*
684 684 * Detect phyints that have been removed from the kernel.
685 685 * Since we can't recreate it here (would require ifconfig plumb
686 686 * logic) we just terminate use of that phyint.
687 687 */
688 688 for (pi = phyints; pi != NULL; pi = next_pi) {
689 689 next_pi = pi->pi_next;
690 690 /*
691 691 * If interface (still) exists in kernel, set
692 692 * pi_state to indicate that.
693 693 */
694 694 if (pi->pi_kernel_state & PI_PRESENT) {
695 695 pi->pi_state |= PI_PRESENT;
696 696 }
697 697
698 698 check_if_removed(pi);
699 699 }
700 700 if (show_ifs)
701 701 phyint_print_all();
702 702 }
703 703
704 704
705 705 /*
706 706 * Router advertisement state machine. Used for everything but timer
707 707 * events which use advertise_event directly.
708 708 */
709 709 void
710 710 check_to_advertise(struct phyint *pi, enum adv_events event)
711 711 {
712 712 uint_t delay;
713 713 enum adv_states old_state = pi->pi_adv_state;
714 714
715 715 if (debug & D_STATE) {
716 716 logmsg(LOG_DEBUG, "check_to_advertise(%s, %d) state %d\n",
717 717 pi->pi_name, (int)event, (int)old_state);
718 718 }
719 719 delay = advertise_event(pi, event, 0);
720 720 if (delay != TIMER_INFINITY) {
721 721 /* Make sure the global next event is updated */
722 722 timer_schedule(delay);
723 723 }
724 724
725 725 if (debug & D_STATE) {
726 726 logmsg(LOG_DEBUG, "check_to_advertise(%s, %d) state %d -> %d\n",
727 727 pi->pi_name, (int)event, (int)old_state,
728 728 (int)pi->pi_adv_state);
729 729 }
730 730 }
731 731
732 732 /*
733 733 * Router advertisement state machine.
734 734 * Return the number of milliseconds until next timeout (TIMER_INFINITY
735 735 * if never).
736 736 * For the ADV_TIMER event the caller passes in the number of milliseconds
737 737 * since the last timer event in the 'elapsed' parameter.
738 738 */
739 739 uint_t
740 740 advertise_event(struct phyint *pi, enum adv_events event, uint_t elapsed)
741 741 {
742 742 uint_t delay;
743 743
744 744 if (debug & D_STATE) {
745 745 logmsg(LOG_DEBUG, "advertise_event(%s, %d, %d) state %d\n",
746 746 pi->pi_name, (int)event, elapsed, (int)pi->pi_adv_state);
747 747 }
748 748 check_daemonize();
749 749 if (!pi->pi_AdvSendAdvertisements)
750 750 return (TIMER_INFINITY);
751 751 if (pi->pi_flags & IFF_NORTEXCH) {
752 752 if (debug & D_PKTOUT) {
753 753 logmsg(LOG_DEBUG, "Suppress sending RA packet on %s "
754 754 "(no route exchange on interface)\n",
755 755 pi->pi_name);
756 756 }
757 757 return (TIMER_INFINITY);
758 758 }
759 759
760 760 switch (event) {
761 761 case ADV_OFF:
762 762 pi->pi_adv_state = NO_ADV;
763 763 return (TIMER_INFINITY);
764 764
765 765 case START_INIT_ADV:
766 766 if (pi->pi_adv_state == INIT_ADV)
767 767 return (pi->pi_adv_time_left);
768 768 pi->pi_adv_count = ND_MAX_INITIAL_RTR_ADVERTISEMENTS;
769 769 pi->pi_adv_time_left = 0;
770 770 pi->pi_adv_state = INIT_ADV;
771 771 break; /* send advertisement */
772 772
773 773 case START_FINAL_ADV:
774 774 if (pi->pi_adv_state == NO_ADV)
775 775 return (TIMER_INFINITY);
776 776 if (pi->pi_adv_state == FINAL_ADV)
777 777 return (pi->pi_adv_time_left);
778 778 pi->pi_adv_count = ND_MAX_FINAL_RTR_ADVERTISEMENTS;
779 779 pi->pi_adv_time_left = 0;
780 780 pi->pi_adv_state = FINAL_ADV;
781 781 break; /* send advertisement */
782 782
783 783 case RECEIVED_SOLICIT:
784 784 if (pi->pi_adv_state == NO_ADV)
785 785 return (TIMER_INFINITY);
786 786 if (pi->pi_adv_state == SOLICIT_ADV) {
787 787 if (pi->pi_adv_time_left != 0)
788 788 return (pi->pi_adv_time_left);
789 789 break;
790 790 }
791 791 delay = GET_RANDOM(0, ND_MAX_RA_DELAY_TIME);
792 792 if (delay < pi->pi_adv_time_left)
793 793 pi->pi_adv_time_left = delay;
794 794 if (pi->pi_adv_time_since_sent < ND_MIN_DELAY_BETWEEN_RAS) {
795 795 /*
796 796 * Send an advertisement (ND_MIN_DELAY_BETWEEN_RAS
797 797 * plus random delay) after the previous
798 798 * advertisement was sent.
799 799 */
800 800 pi->pi_adv_time_left = delay +
801 801 ND_MIN_DELAY_BETWEEN_RAS -
802 802 pi->pi_adv_time_since_sent;
803 803 }
804 804 pi->pi_adv_state = SOLICIT_ADV;
805 805 break;
806 806
807 807 case ADV_TIMER:
808 808 if (pi->pi_adv_state == NO_ADV)
809 809 return (TIMER_INFINITY);
810 810 /* Decrease time left */
811 811 if (pi->pi_adv_time_left >= elapsed)
812 812 pi->pi_adv_time_left -= elapsed;
813 813 else
814 814 pi->pi_adv_time_left = 0;
815 815
816 816 /* Increase time since last advertisement was sent */
817 817 pi->pi_adv_time_since_sent += elapsed;
818 818 break;
819 819 default:
820 820 logmsg(LOG_ERR, "advertise_event: Unknown event %d\n",
821 821 (int)event);
822 822 return (TIMER_INFINITY);
823 823 }
824 824
825 825 if (pi->pi_adv_time_left != 0)
826 826 return (pi->pi_adv_time_left);
827 827
828 828 /* Send advertisement and calculate next time to send */
829 829 if (pi->pi_adv_state == FINAL_ADV) {
830 830 /* Omit the prefixes */
831 831 advertise(&v6allnodes, pi, _B_TRUE);
832 832 } else {
833 833 advertise(&v6allnodes, pi, _B_FALSE);
834 834 }
835 835 pi->pi_adv_time_since_sent = 0;
836 836
837 837 switch (pi->pi_adv_state) {
838 838 case SOLICIT_ADV:
839 839 /*
840 840 * The solicited advertisement has been sent.
841 841 * Revert to periodic advertisements.
842 842 */
843 843 pi->pi_adv_state = REG_ADV;
844 844 /* FALLTHRU */
845 845 case REG_ADV:
846 846 pi->pi_adv_time_left =
847 847 GET_RANDOM(1000 * pi->pi_MinRtrAdvInterval,
848 848 1000 * pi->pi_MaxRtrAdvInterval);
849 849 break;
850 850
851 851 case INIT_ADV:
852 852 if (--pi->pi_adv_count > 0) {
853 853 delay = GET_RANDOM(1000 * pi->pi_MinRtrAdvInterval,
854 854 1000 * pi->pi_MaxRtrAdvInterval);
855 855 if (delay > ND_MAX_INITIAL_RTR_ADVERT_INTERVAL)
856 856 delay = ND_MAX_INITIAL_RTR_ADVERT_INTERVAL;
857 857 pi->pi_adv_time_left = delay;
858 858 } else {
859 859 pi->pi_adv_time_left =
860 860 GET_RANDOM(1000 * pi->pi_MinRtrAdvInterval,
861 861 1000 * pi->pi_MaxRtrAdvInterval);
862 862 pi->pi_adv_state = REG_ADV;
863 863 }
864 864 break;
865 865
866 866 case FINAL_ADV:
867 867 if (--pi->pi_adv_count > 0) {
868 868 pi->pi_adv_time_left =
869 869 ND_MAX_INITIAL_RTR_ADVERT_INTERVAL;
870 870 } else {
871 871 pi->pi_adv_state = NO_ADV;
872 872 }
873 873 break;
874 874 }
875 875 if (pi->pi_adv_state != NO_ADV)
876 876 return (pi->pi_adv_time_left);
877 877 else
878 878 return (TIMER_INFINITY);
879 879 }
880 880
881 881 /*
882 882 * Router solicitation state machine. Used for everything but timer
883 883 * events which use solicit_event directly.
884 884 */
885 885 void
886 886 check_to_solicit(struct phyint *pi, enum solicit_events event)
887 887 {
888 888 uint_t delay;
889 889 enum solicit_states old_state = pi->pi_sol_state;
890 890
891 891 if (debug & D_STATE) {
892 892 logmsg(LOG_DEBUG, "check_to_solicit(%s, %d) state %d\n",
893 893 pi->pi_name, (int)event, (int)old_state);
894 894 }
895 895 delay = solicit_event(pi, event, 0);
896 896 if (delay != TIMER_INFINITY) {
897 897 /* Make sure the global next event is updated */
898 898 timer_schedule(delay);
899 899 }
900 900
901 901 if (debug & D_STATE) {
902 902 logmsg(LOG_DEBUG, "check_to_solicit(%s, %d) state %d -> %d\n",
903 903 pi->pi_name, (int)event, (int)old_state,
904 904 (int)pi->pi_sol_state);
905 905 }
906 906 }
907 907
908 908 static void
909 909 daemonize_ndpd(void)
910 910 {
911 911 FILE *pidfp;
912 912 mode_t pidmode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* 0644 */
913 913 struct itimerval it;
914 914 boolean_t timerval = _B_TRUE;
915 915
916 916 /*
917 917 * Need to get current timer settings so they can be restored
↓ open down ↓ |
917 lines elided |
↑ open up ↑ |
918 918 * after the fork(), as the it_value and it_interval values for
919 919 * the ITIMER_REAL timer are reset to 0 in the child process.
920 920 */
921 921 if (getitimer(ITIMER_REAL, &it) < 0) {
922 922 if (debug & D_TIMER)
923 923 logmsg(LOG_DEBUG,
924 924 "daemonize_ndpd: failed to get itimerval\n");
925 925 timerval = _B_FALSE;
926 926 }
927 927
928 + /* Open pid file, blow away any existing file if it exists. */
929 + if ((pidfp = fopen(PATH_PID, "w")) == NULL) {
930 + (void) fprintf(stderr, "%s: unable to open " PATH_PID ": %s\n",
931 + argv0[0], strerror(errno));
932 + }
933 +
928 934 /* Daemonize. */
929 - switch (fork()) {
930 - case 0:
931 - /* Child */
932 - break;
933 - case -1:
935 + if (daemon(0, 0) == -1) {
934 936 logperror("fork");
935 937 exit(1);
936 - default:
937 - /* Parent */
938 - _exit(0);
939 938 }
940 939
941 - /* Store our process id, blow away any existing file if it exists. */
942 - if ((pidfp = fopen(PATH_PID, "w")) == NULL) {
943 - (void) fprintf(stderr, "%s: unable to open " PATH_PID ": %s\n",
944 - argv0[0], strerror(errno));
945 - } else {
940 + /* Store our process id */
941 + if (pidfp != NULL) {
946 942 (void) fprintf(pidfp, "%ld\n", getpid());
947 943 (void) fclose(pidfp);
948 944 (void) chmod(PATH_PID, pidmode);
949 945 }
950 946
951 - (void) close(0);
952 - (void) close(1);
953 - (void) close(2);
954 -
955 - (void) chdir("/");
956 - (void) open("/dev/null", O_RDWR);
957 - (void) dup2(0, 1);
958 - (void) dup2(0, 2);
959 - (void) setsid();
960 -
961 947 already_daemonized = _B_TRUE;
962 948
963 949 /*
964 950 * Restore timer values, if we were able to save them; if not,
965 951 * check and set the right value by calling run_timeouts().
966 952 */
967 953 if (timerval) {
968 954 if (setitimer(ITIMER_REAL, &it, NULL) < 0) {
969 955 logperror("daemonize_ndpd: setitimer");
970 956 exit(2);
971 957 }
972 958 } else {
973 959 run_timeouts();
974 960 }
975 961 }
976 962
977 963 /*
978 964 * Check to see if the time is right to daemonize. The right time is when:
979 965 *
980 966 * 1. We haven't already daemonized.
981 967 * 2. We are not in debug mode.
982 968 * 3. All interfaces are marked IFF_NOXMIT.
983 969 * 4. All non-router interfaces have their prefixes set up and we're
984 970 * done sending router solicitations on those interfaces without
985 971 * prefixes.
986 972 */
987 973 static void
988 974 check_daemonize(void)
989 975 {
990 976 struct phyint *pi;
991 977
992 978 if (already_daemonized || debug != 0)
993 979 return;
994 980
995 981 for (pi = phyints; pi != NULL; pi = pi->pi_next) {
996 982 if (!(pi->pi_flags & IFF_NOXMIT))
997 983 break;
998 984 }
999 985
1000 986 /*
1001 987 * If we can't transmit on any of the interfaces there is no reason
1002 988 * to hold up progress.
1003 989 */
1004 990 if (pi == NULL) {
1005 991 daemonize_ndpd();
1006 992 return;
1007 993 }
1008 994
1009 995 /* Check all interfaces. If any are still soliciting, just return. */
1010 996 for (pi = phyints; pi != NULL; pi = pi->pi_next) {
1011 997 if (pi->pi_AdvSendAdvertisements ||
1012 998 !(pi->pi_kernel_state & PI_PRESENT))
1013 999 continue;
1014 1000
1015 1001 if (pi->pi_sol_state == INIT_SOLICIT)
1016 1002 return;
1017 1003 }
1018 1004
1019 1005 daemonize_ndpd();
1020 1006 }
1021 1007
1022 1008 /*
1023 1009 * Router solicitation state machine.
1024 1010 * Return the number of milliseconds until next timeout (TIMER_INFINITY
1025 1011 * if never).
1026 1012 * For the SOL_TIMER event the caller passes in the number of milliseconds
1027 1013 * since the last timer event in the 'elapsed' parameter.
1028 1014 */
1029 1015 uint_t
1030 1016 solicit_event(struct phyint *pi, enum solicit_events event, uint_t elapsed)
1031 1017 {
1032 1018 if (debug & D_STATE) {
1033 1019 logmsg(LOG_DEBUG, "solicit_event(%s, %d, %d) state %d\n",
1034 1020 pi->pi_name, (int)event, elapsed, (int)pi->pi_sol_state);
1035 1021 }
1036 1022
1037 1023 if (pi->pi_AdvSendAdvertisements)
1038 1024 return (TIMER_INFINITY);
1039 1025 if (pi->pi_flags & IFF_NORTEXCH) {
1040 1026 if (debug & D_PKTOUT) {
1041 1027 logmsg(LOG_DEBUG, "Suppress sending RS packet on %s "
1042 1028 "(no route exchange on interface)\n",
1043 1029 pi->pi_name);
1044 1030 }
1045 1031 return (TIMER_INFINITY);
1046 1032 }
1047 1033
1048 1034 switch (event) {
1049 1035 case SOLICIT_OFF:
1050 1036 pi->pi_sol_state = NO_SOLICIT;
1051 1037 check_daemonize();
1052 1038 return (TIMER_INFINITY);
1053 1039
1054 1040 case SOLICIT_DONE:
1055 1041 pi->pi_sol_state = DONE_SOLICIT;
1056 1042 check_daemonize();
1057 1043 return (TIMER_INFINITY);
1058 1044
1059 1045 case RESTART_INIT_SOLICIT:
1060 1046 /*
1061 1047 * This event allows us to start solicitation over again
1062 1048 * without losing the RA flags. We start solicitation over
1063 1049 * when we are missing an interface prefix for a newly-
1064 1050 * encountered DHCP interface.
1065 1051 */
1066 1052 if (pi->pi_sol_state == INIT_SOLICIT)
1067 1053 return (pi->pi_sol_time_left);
1068 1054 pi->pi_sol_count = ND_MAX_RTR_SOLICITATIONS;
1069 1055 pi->pi_sol_time_left =
1070 1056 GET_RANDOM(0, ND_MAX_RTR_SOLICITATION_DELAY);
1071 1057 pi->pi_sol_state = INIT_SOLICIT;
1072 1058 break;
1073 1059
1074 1060 case START_INIT_SOLICIT:
1075 1061 if (pi->pi_sol_state == INIT_SOLICIT)
1076 1062 return (pi->pi_sol_time_left);
1077 1063 pi->pi_ra_flags = 0;
1078 1064 pi->pi_sol_count = ND_MAX_RTR_SOLICITATIONS;
1079 1065 pi->pi_sol_time_left =
1080 1066 GET_RANDOM(0, ND_MAX_RTR_SOLICITATION_DELAY);
1081 1067 pi->pi_sol_state = INIT_SOLICIT;
1082 1068 break;
1083 1069
1084 1070 case SOL_TIMER:
1085 1071 if (pi->pi_sol_state == NO_SOLICIT)
1086 1072 return (TIMER_INFINITY);
1087 1073 /* Decrease time left */
1088 1074 if (pi->pi_sol_time_left >= elapsed)
1089 1075 pi->pi_sol_time_left -= elapsed;
1090 1076 else
1091 1077 pi->pi_sol_time_left = 0;
1092 1078 break;
1093 1079 default:
1094 1080 logmsg(LOG_ERR, "solicit_event: Unknown event %d\n",
1095 1081 (int)event);
1096 1082 return (TIMER_INFINITY);
1097 1083 }
1098 1084
1099 1085 if (pi->pi_sol_time_left != 0)
1100 1086 return (pi->pi_sol_time_left);
1101 1087
1102 1088 /* Send solicitation and calculate next time */
1103 1089 switch (pi->pi_sol_state) {
1104 1090 case INIT_SOLICIT:
1105 1091 solicit(&v6allrouters, pi);
1106 1092 if (--pi->pi_sol_count == 0) {
1107 1093 if (debug & D_STATE) {
1108 1094 logmsg(LOG_DEBUG, "solicit_event: no routers "
1109 1095 "found on %s; assuming default flags\n",
1110 1096 pi->pi_name);
1111 1097 }
1112 1098 if (pi->pi_autoconf && pi->pi_StatefulAddrConf) {
1113 1099 pi->pi_ra_flags |= ND_RA_FLAG_MANAGED |
1114 1100 ND_RA_FLAG_OTHER;
1115 1101 start_dhcp(pi);
1116 1102 }
1117 1103 pi->pi_sol_state = DONE_SOLICIT;
1118 1104 check_daemonize();
1119 1105 return (TIMER_INFINITY);
1120 1106 }
1121 1107 pi->pi_sol_time_left = ND_RTR_SOLICITATION_INTERVAL;
1122 1108 return (pi->pi_sol_time_left);
1123 1109 case NO_SOLICIT:
1124 1110 case DONE_SOLICIT:
1125 1111 return (TIMER_INFINITY);
1126 1112 default:
1127 1113 return (pi->pi_sol_time_left);
1128 1114 }
1129 1115 }
1130 1116
1131 1117 /*
1132 1118 * Timer mechanism using relative time (in milliseconds) from the
1133 1119 * previous timer event. Timers exceeding TIMER_INFINITY milliseconds
1134 1120 * will fire after TIMER_INFINITY milliseconds.
1135 1121 */
1136 1122 static uint_t timer_previous; /* When last SIGALRM occurred */
1137 1123 static uint_t timer_next; /* Currently scheduled timeout */
1138 1124
1139 1125 static void
1140 1126 timer_init(void)
1141 1127 {
1142 1128 timer_previous = getcurrenttime();
1143 1129 timer_next = TIMER_INFINITY;
1144 1130 run_timeouts();
1145 1131 }
1146 1132
1147 1133 /*
1148 1134 * Make sure the next SIGALRM occurs delay milliseconds from the current
1149 1135 * time if not earlier.
1150 1136 * Handles getcurrenttime (32 bit integer holding milliseconds) wraparound
1151 1137 * by treating differences greater than 0x80000000 as negative.
1152 1138 */
1153 1139 void
1154 1140 timer_schedule(uint_t delay)
1155 1141 {
1156 1142 uint_t now;
1157 1143 struct itimerval itimerval;
1158 1144
1159 1145 now = getcurrenttime();
1160 1146 if (debug & D_TIMER) {
1161 1147 logmsg(LOG_DEBUG, "timer_schedule(%u): now %u next %u\n",
1162 1148 delay, now, timer_next);
1163 1149 }
1164 1150 /* Will this timer occur before the currently scheduled SIGALRM? */
1165 1151 if (delay >= timer_next - now) {
1166 1152 if (debug & D_TIMER) {
1167 1153 logmsg(LOG_DEBUG, "timer_schedule(%u): no action - "
1168 1154 "next in %u ms\n",
1169 1155 delay, timer_next - now);
1170 1156 }
1171 1157 return;
1172 1158 }
1173 1159 if (delay == 0) {
1174 1160 /* Minimum allowed delay */
1175 1161 delay = 1;
1176 1162 }
1177 1163 timer_next = now + delay;
1178 1164
1179 1165 itimerval.it_value.tv_sec = delay / 1000;
1180 1166 itimerval.it_value.tv_usec = (delay % 1000) * 1000;
1181 1167 itimerval.it_interval.tv_sec = 0;
1182 1168 itimerval.it_interval.tv_usec = 0;
1183 1169 if (debug & D_TIMER) {
1184 1170 logmsg(LOG_DEBUG, "timer_schedule(%u): sec %lu usec %lu\n",
1185 1171 delay,
1186 1172 itimerval.it_value.tv_sec, itimerval.it_value.tv_usec);
1187 1173 }
1188 1174 if (setitimer(ITIMER_REAL, &itimerval, NULL) < 0) {
1189 1175 logperror("timer_schedule: setitimer");
1190 1176 exit(2);
1191 1177 }
1192 1178 }
1193 1179
1194 1180 /*
1195 1181 * Conditional running of timer. If more than 'minimal_time' millseconds
1196 1182 * since the timer routines were last run we run them.
1197 1183 * Used when packets arrive.
1198 1184 */
1199 1185 static void
1200 1186 conditional_run_timeouts(uint_t minimal_time)
1201 1187 {
1202 1188 uint_t now;
1203 1189 uint_t elapsed;
1204 1190
1205 1191 now = getcurrenttime();
1206 1192 elapsed = now - timer_previous;
1207 1193 if (elapsed > minimal_time) {
1208 1194 if (debug & D_TIMER) {
1209 1195 logmsg(LOG_DEBUG, "conditional_run_timeouts: "
1210 1196 "elapsed %d\n", elapsed);
1211 1197 }
1212 1198 run_timeouts();
1213 1199 }
1214 1200 }
1215 1201
1216 1202 /*
1217 1203 * Timer has fired.
1218 1204 * Determine when the next timer event will occur by asking all
1219 1205 * the timer routines.
1220 1206 * Should not be called from a timer routine but in some cases this is
1221 1207 * done because the code doesn't know that e.g. it was called from
1222 1208 * ifconfig_timer(). In this case the nested run_timeouts will just return but
1223 1209 * the running run_timeouts will ensure to call all the timer functions by
1224 1210 * looping once more.
1225 1211 */
1226 1212 static void
1227 1213 run_timeouts(void)
1228 1214 {
1229 1215 uint_t now;
1230 1216 uint_t elapsed;
1231 1217 uint_t next;
1232 1218 uint_t nexti;
1233 1219 struct phyint *pi;
1234 1220 struct phyint *next_pi;
1235 1221 struct prefix *pr;
1236 1222 struct prefix *next_pr;
1237 1223 struct adv_prefix *adv_pr;
1238 1224 struct adv_prefix *next_adv_pr;
1239 1225 struct router *dr;
1240 1226 struct router *next_dr;
1241 1227 static boolean_t timeout_running;
1242 1228 static boolean_t do_retry;
1243 1229
1244 1230 if (timeout_running) {
1245 1231 if (debug & D_TIMER)
1246 1232 logmsg(LOG_DEBUG, "run_timeouts: nested call\n");
1247 1233 do_retry = _B_TRUE;
1248 1234 return;
1249 1235 }
1250 1236 timeout_running = _B_TRUE;
1251 1237 retry:
1252 1238 /* How much time since the last time we were called? */
1253 1239 now = getcurrenttime();
1254 1240 elapsed = now - timer_previous;
1255 1241 timer_previous = now;
1256 1242
1257 1243 if (debug & D_TIMER)
1258 1244 logmsg(LOG_DEBUG, "run_timeouts: elapsed %d\n", elapsed);
1259 1245
1260 1246 next = TIMER_INFINITY;
1261 1247 for (pi = phyints; pi != NULL; pi = next_pi) {
1262 1248 next_pi = pi->pi_next;
1263 1249 nexti = phyint_timer(pi, elapsed);
1264 1250 if (nexti != TIMER_INFINITY && nexti < next)
1265 1251 next = nexti;
1266 1252 if (debug & D_TIMER) {
1267 1253 logmsg(LOG_DEBUG, "run_timeouts (pi %s): %d -> %u ms\n",
1268 1254 pi->pi_name, nexti, next);
1269 1255 }
1270 1256 for (pr = pi->pi_prefix_list; pr != NULL; pr = next_pr) {
1271 1257 next_pr = pr->pr_next;
1272 1258 nexti = prefix_timer(pr, elapsed);
1273 1259 if (nexti != TIMER_INFINITY && nexti < next)
1274 1260 next = nexti;
1275 1261 if (debug & D_TIMER) {
1276 1262 logmsg(LOG_DEBUG, "run_timeouts (pr %s): "
1277 1263 "%d -> %u ms\n", pr->pr_name, nexti, next);
1278 1264 }
1279 1265 }
1280 1266 for (adv_pr = pi->pi_adv_prefix_list; adv_pr != NULL;
1281 1267 adv_pr = next_adv_pr) {
1282 1268 next_adv_pr = adv_pr->adv_pr_next;
1283 1269 nexti = adv_prefix_timer(adv_pr, elapsed);
1284 1270 if (nexti != TIMER_INFINITY && nexti < next)
1285 1271 next = nexti;
1286 1272 if (debug & D_TIMER) {
1287 1273 logmsg(LOG_DEBUG, "run_timeouts "
1288 1274 "(adv pr on %s): %d -> %u ms\n",
1289 1275 adv_pr->adv_pr_physical->pi_name,
1290 1276 nexti, next);
1291 1277 }
1292 1278 }
1293 1279 for (dr = pi->pi_router_list; dr != NULL; dr = next_dr) {
1294 1280 next_dr = dr->dr_next;
1295 1281 nexti = router_timer(dr, elapsed);
1296 1282 if (nexti != TIMER_INFINITY && nexti < next)
1297 1283 next = nexti;
1298 1284 if (debug & D_TIMER) {
1299 1285 logmsg(LOG_DEBUG, "run_timeouts (dr): "
1300 1286 "%d -> %u ms\n", nexti, next);
1301 1287 }
1302 1288 }
1303 1289 if (pi->pi_TmpAddrsEnabled) {
1304 1290 nexti = tmptoken_timer(pi, elapsed);
1305 1291 if (nexti != TIMER_INFINITY && nexti < next)
1306 1292 next = nexti;
1307 1293 if (debug & D_TIMER) {
1308 1294 logmsg(LOG_DEBUG, "run_timeouts (tmp on %s): "
1309 1295 "%d -> %u ms\n", pi->pi_name, nexti, next);
1310 1296 }
1311 1297 }
1312 1298 }
1313 1299 /*
1314 1300 * Make sure the timer functions are run at least once
1315 1301 * an hour.
1316 1302 */
1317 1303 if (next == TIMER_INFINITY)
1318 1304 next = 3600 * 1000; /* 1 hour */
1319 1305
1320 1306 if (debug & D_TIMER)
1321 1307 logmsg(LOG_DEBUG, "run_timeouts: %u ms\n", next);
1322 1308 timer_schedule(next);
1323 1309 if (do_retry) {
1324 1310 if (debug & D_TIMER)
1325 1311 logmsg(LOG_DEBUG, "run_timeouts: retry\n");
1326 1312 do_retry = _B_FALSE;
1327 1313 goto retry;
1328 1314 }
1329 1315 timeout_running = _B_FALSE;
1330 1316 }
1331 1317
1332 1318 static int eventpipe_read = -1; /* Used for synchronous signal delivery */
1333 1319 static int eventpipe_write = -1;
1334 1320
1335 1321 /*
1336 1322 * Ensure that signals are processed synchronously with the rest of
1337 1323 * the code by just writing a one character signal number on the pipe.
1338 1324 * The poll loop will pick this up and process the signal event.
1339 1325 */
1340 1326 static void
1341 1327 sig_handler(int signo)
1342 1328 {
1343 1329 uchar_t buf = (uchar_t)signo;
1344 1330
1345 1331 if (eventpipe_write == -1) {
1346 1332 logmsg(LOG_ERR, "sig_handler: no pipe\n");
1347 1333 return;
1348 1334 }
1349 1335 if (write(eventpipe_write, &buf, sizeof (buf)) < 0)
1350 1336 logperror("sig_handler: write");
1351 1337 }
1352 1338
1353 1339 /*
1354 1340 * Pick up a signal "byte" from the pipe and process it.
1355 1341 */
1356 1342 static void
1357 1343 in_signal(int fd)
1358 1344 {
1359 1345 uchar_t buf;
1360 1346 struct phyint *pi;
1361 1347 struct phyint *next_pi;
1362 1348
1363 1349 switch (read(fd, &buf, sizeof (buf))) {
1364 1350 case -1:
1365 1351 logperror("in_signal: read");
1366 1352 exit(1);
1367 1353 /* NOTREACHED */
1368 1354 case 1:
1369 1355 break;
1370 1356 case 0:
1371 1357 logmsg(LOG_ERR, "in_signal: read eof\n");
1372 1358 exit(1);
1373 1359 /* NOTREACHED */
1374 1360 default:
1375 1361 logmsg(LOG_ERR, "in_signal: read > 1\n");
1376 1362 exit(1);
1377 1363 }
1378 1364
1379 1365 if (debug & D_TIMER)
1380 1366 logmsg(LOG_DEBUG, "in_signal() got %d\n", buf);
1381 1367
1382 1368 switch (buf) {
1383 1369 case SIGALRM:
1384 1370 if (debug & D_TIMER) {
1385 1371 uint_t now = getcurrenttime();
1386 1372
1387 1373 logmsg(LOG_DEBUG, "in_signal(SIGALRM) delta %u\n",
1388 1374 now - timer_next);
1389 1375 }
1390 1376 timer_next = TIMER_INFINITY;
1391 1377 run_timeouts();
1392 1378 break;
1393 1379 case SIGHUP:
1394 1380 /* Re-read config file by exec'ing ourselves */
1395 1381 for (pi = phyints; pi != NULL; pi = next_pi) {
1396 1382 next_pi = pi->pi_next;
1397 1383 if (pi->pi_AdvSendAdvertisements)
1398 1384 check_to_advertise(pi, START_FINAL_ADV);
1399 1385
1400 1386 /*
1401 1387 * Remove all the configured addresses.
1402 1388 * Remove the addrobj names created with ipmgmtd.
1403 1389 * Release the dhcpv6 addresses if any.
1404 1390 * Cleanup the phyints.
1405 1391 */
1406 1392 phyint_delete(pi);
1407 1393 }
1408 1394
1409 1395 /*
1410 1396 * Prevent fd leaks. Everything gets re-opened at start-up
1411 1397 * time. 0, 1, and 2 are closed and re-opened as
1412 1398 * /dev/null, so we'll leave those open.
1413 1399 */
1414 1400 closefrom(3);
1415 1401
1416 1402 logmsg(LOG_ERR, "SIGHUP: restart and reread config file\n");
1417 1403 (void) execv(argv0[0], argv0);
1418 1404 (void) unlink(PATH_PID);
1419 1405 _exit(0177);
1420 1406 /* NOTREACHED */
1421 1407 case SIGUSR1:
1422 1408 logmsg(LOG_DEBUG, "Printing configuration:\n");
1423 1409 phyint_print_all();
1424 1410 break;
1425 1411 case SIGINT:
1426 1412 case SIGTERM:
1427 1413 case SIGQUIT:
1428 1414 for (pi = phyints; pi != NULL; pi = next_pi) {
1429 1415 next_pi = pi->pi_next;
1430 1416 if (pi->pi_AdvSendAdvertisements)
1431 1417 check_to_advertise(pi, START_FINAL_ADV);
1432 1418
1433 1419 phyint_delete(pi);
1434 1420 }
1435 1421 (void) unlink(NDPD_SNMP_SOCKET);
1436 1422 (void) unlink(PATH_PID);
1437 1423 exit(0);
1438 1424 /* NOTREACHED */
1439 1425 case 255:
1440 1426 /*
1441 1427 * Special "signal" from loopback_ra_enqueue.
1442 1428 * Handle any queued loopback router advertisements.
1443 1429 */
1444 1430 loopback_ra_dequeue();
1445 1431 break;
1446 1432 default:
1447 1433 logmsg(LOG_ERR, "in_signal: unknown signal: %d\n", buf);
1448 1434 }
1449 1435 }
1450 1436
1451 1437 /*
1452 1438 * Create pipe for signal delivery and set up signal handlers.
1453 1439 */
1454 1440 static void
1455 1441 setup_eventpipe(void)
1456 1442 {
1457 1443 int fds[2];
1458 1444 struct sigaction act;
1459 1445
1460 1446 if ((pipe(fds)) < 0) {
1461 1447 logperror("setup_eventpipe: pipe");
1462 1448 exit(1);
1463 1449 }
1464 1450 eventpipe_read = fds[0];
1465 1451 eventpipe_write = fds[1];
1466 1452 if (poll_add(eventpipe_read) == -1) {
1467 1453 exit(1);
1468 1454 }
1469 1455 act.sa_handler = sig_handler;
1470 1456 act.sa_flags = SA_RESTART;
1471 1457 (void) sigaction(SIGALRM, &act, NULL);
1472 1458
1473 1459 (void) sigset(SIGHUP, sig_handler);
1474 1460 (void) sigset(SIGUSR1, sig_handler);
1475 1461 (void) sigset(SIGTERM, sig_handler);
1476 1462 (void) sigset(SIGINT, sig_handler);
1477 1463 (void) sigset(SIGQUIT, sig_handler);
1478 1464 }
1479 1465
1480 1466 /*
1481 1467 * Create a routing socket for receiving RTM_IFINFO messages and initialize
1482 1468 * the routing socket message header and as much of the sockaddrs as possible.
1483 1469 */
1484 1470 static int
1485 1471 setup_rtsock(void)
1486 1472 {
1487 1473 int s;
1488 1474 int ret;
1489 1475 char *cp;
1490 1476 struct sockaddr_in6 *sin6;
1491 1477
1492 1478 s = socket(PF_ROUTE, SOCK_RAW, AF_INET6);
1493 1479 if (s == -1) {
1494 1480 logperror("socket(PF_ROUTE)");
1495 1481 exit(1);
1496 1482 }
1497 1483 ret = fcntl(s, F_SETFL, O_NDELAY|O_NONBLOCK);
1498 1484 if (ret < 0) {
1499 1485 logperror("fcntl(O_NDELAY)");
1500 1486 exit(1);
1501 1487 }
1502 1488 if (poll_add(s) == -1) {
1503 1489 exit(1);
1504 1490 }
1505 1491
1506 1492 /*
1507 1493 * Allocate storage for the routing socket message.
1508 1494 */
1509 1495 rt_msg = (struct rt_msghdr *)malloc(NDP_RTM_MSGLEN);
1510 1496 if (rt_msg == NULL) {
1511 1497 logperror("malloc");
1512 1498 exit(1);
1513 1499 }
1514 1500
1515 1501 /*
1516 1502 * Initialize the routing socket message by zero-filling it and then
1517 1503 * setting the fields where are constant through the lifetime of the
1518 1504 * process.
1519 1505 */
1520 1506 bzero(rt_msg, NDP_RTM_MSGLEN);
1521 1507 rt_msg->rtm_msglen = NDP_RTM_MSGLEN;
1522 1508 rt_msg->rtm_version = RTM_VERSION;
1523 1509 rt_msg->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK | RTA_IFP;
1524 1510 rt_msg->rtm_pid = getpid();
1525 1511 if (rt_msg->rtm_pid < 0) {
1526 1512 logperror("getpid");
1527 1513 exit(1);
1528 1514 }
1529 1515
1530 1516 /*
1531 1517 * The RTA_DST sockaddr does not change during the lifetime of the
1532 1518 * process so it can be completely initialized at this time.
1533 1519 */
1534 1520 cp = (char *)rt_msg + sizeof (struct rt_msghdr);
1535 1521 sin6 = (struct sockaddr_in6 *)cp;
1536 1522 sin6->sin6_family = AF_INET6;
1537 1523 sin6->sin6_addr = in6addr_any;
1538 1524
1539 1525 /*
1540 1526 * Initialize the constant portion of the RTA_GATEWAY sockaddr.
1541 1527 */
1542 1528 cp += sizeof (struct sockaddr_in6);
1543 1529 rta_gateway = (struct sockaddr_in6 *)cp;
1544 1530 rta_gateway->sin6_family = AF_INET6;
1545 1531
1546 1532 /*
1547 1533 * The RTA_NETMASK sockaddr does not change during the lifetime of the
1548 1534 * process so it can be completely initialized at this time.
1549 1535 */
1550 1536 cp += sizeof (struct sockaddr_in6);
1551 1537 sin6 = (struct sockaddr_in6 *)cp;
1552 1538 sin6->sin6_family = AF_INET6;
1553 1539 sin6->sin6_addr = in6addr_any;
1554 1540
1555 1541 /*
1556 1542 * Initialize the constant portion of the RTA_IFP sockaddr.
1557 1543 */
1558 1544 cp += sizeof (struct sockaddr_in6);
1559 1545 rta_ifp = (struct sockaddr_dl *)cp;
1560 1546 rta_ifp->sdl_family = AF_LINK;
1561 1547
1562 1548 return (s);
1563 1549 }
1564 1550
1565 1551 static int
1566 1552 setup_mibsock(void)
1567 1553 {
1568 1554 int sock;
1569 1555 int ret;
1570 1556 int len;
1571 1557 struct sockaddr_un laddr;
1572 1558
1573 1559 sock = socket(AF_UNIX, SOCK_DGRAM, 0);
1574 1560 if (sock == -1) {
1575 1561 logperror("setup_mibsock: socket(AF_UNIX)");
1576 1562 exit(1);
1577 1563 }
1578 1564
1579 1565 bzero(&laddr, sizeof (laddr));
1580 1566 laddr.sun_family = AF_UNIX;
1581 1567
1582 1568 (void) strncpy(laddr.sun_path, NDPD_SNMP_SOCKET,
1583 1569 sizeof (laddr.sun_path));
1584 1570 len = sizeof (struct sockaddr_un);
1585 1571
1586 1572 (void) unlink(NDPD_SNMP_SOCKET);
1587 1573 ret = bind(sock, (struct sockaddr *)&laddr, len);
1588 1574 if (ret < 0) {
1589 1575 logperror("setup_mibsock: bind\n");
1590 1576 exit(1);
1591 1577 }
1592 1578
1593 1579 ret = fcntl(sock, F_SETFL, O_NONBLOCK);
1594 1580 if (ret < 0) {
1595 1581 logperror("fcntl(O_NONBLOCK)");
1596 1582 exit(1);
1597 1583 }
1598 1584 if (poll_add(sock) == -1) {
1599 1585 exit(1);
1600 1586 }
1601 1587 return (sock);
1602 1588 }
1603 1589
1604 1590 /*
1605 1591 * Retrieve one routing socket message. If RTM_IFINFO indicates
1606 1592 * new phyint do a full scan of the interfaces. If RTM_IFINFO
1607 1593 * indicates an existing phyint, only scan that phyint and associated
1608 1594 * prefixes.
1609 1595 */
1610 1596 static void
1611 1597 process_rtsock(int rtsock)
1612 1598 {
1613 1599 int n;
1614 1600 #define MSG_SIZE 2048/8
1615 1601 int64_t msg[MSG_SIZE];
1616 1602 struct rt_msghdr *rtm;
1617 1603 struct if_msghdr *ifm;
1618 1604 struct phyint *pi;
1619 1605 struct prefix *pr;
1620 1606 boolean_t need_initifs = _B_FALSE;
1621 1607 boolean_t need_ifscan = _B_FALSE;
1622 1608 int64_t ifscan_msg[10][MSG_SIZE];
1623 1609 int ifscan_index = 0;
1624 1610 int i;
1625 1611
1626 1612 /* Empty the rtsock and coealesce all the work that we have */
1627 1613 while (ifscan_index < 10) {
1628 1614 n = read(rtsock, msg, sizeof (msg));
1629 1615 if (n <= 0) {
1630 1616 /* No more messages */
1631 1617 break;
1632 1618 }
1633 1619 rtm = (struct rt_msghdr *)msg;
1634 1620 if (rtm->rtm_version != RTM_VERSION) {
1635 1621 logmsg(LOG_ERR,
1636 1622 "process_rtsock: version %d not understood\n",
1637 1623 rtm->rtm_version);
1638 1624 return;
1639 1625 }
1640 1626 switch (rtm->rtm_type) {
1641 1627 case RTM_NEWADDR:
1642 1628 case RTM_DELADDR:
1643 1629 /*
1644 1630 * Some logical interface has changed - have to scan
1645 1631 * everything to determine what actually changed.
1646 1632 */
1647 1633 if (debug & D_IFSCAN) {
1648 1634 logmsg(LOG_DEBUG, "process_rtsock: "
1649 1635 "message %d\n", rtm->rtm_type);
1650 1636 }
1651 1637 need_initifs = _B_TRUE;
1652 1638 break;
1653 1639 case RTM_IFINFO:
1654 1640 need_ifscan = _B_TRUE;
1655 1641 (void) memcpy(ifscan_msg[ifscan_index], rtm,
1656 1642 sizeof (msg));
1657 1643 ifscan_index++;
1658 1644 /* Handled below */
1659 1645 break;
1660 1646 default:
1661 1647 /* Not interesting */
1662 1648 break;
1663 1649 }
1664 1650 }
1665 1651 /*
1666 1652 * If we do full scan i.e initifs, we don't need to
1667 1653 * scan a particular interface as we should have
1668 1654 * done that as part of initifs.
1669 1655 */
1670 1656 if (need_initifs) {
1671 1657 initifs(_B_FALSE);
1672 1658 return;
1673 1659 }
1674 1660
1675 1661 if (!need_ifscan)
1676 1662 return;
1677 1663
1678 1664 for (i = 0; i < ifscan_index; i++) {
1679 1665 ifm = (struct if_msghdr *)ifscan_msg[i];
1680 1666 if (debug & D_IFSCAN)
1681 1667 logmsg(LOG_DEBUG, "process_rtsock: index %d\n",
1682 1668 ifm->ifm_index);
1683 1669
1684 1670 pi = phyint_lookup_on_index(ifm->ifm_index);
1685 1671 if (pi == NULL) {
1686 1672 /*
1687 1673 * A new physical interface. Do a full scan of the
1688 1674 * to catch any new logical interfaces.
1689 1675 */
1690 1676 initifs(_B_FALSE);
1691 1677 return;
1692 1678 }
1693 1679
1694 1680 if (ifm->ifm_flags != (uint_t)pi->pi_flags) {
1695 1681 if (debug & D_IFSCAN) {
1696 1682 logmsg(LOG_DEBUG, "process_rtsock: clr for "
1697 1683 "%s old flags 0x%llx new flags 0x%x\n",
1698 1684 pi->pi_name, pi->pi_flags, ifm->ifm_flags);
1699 1685 }
1700 1686 }
1701 1687
1702 1688
1703 1689 /*
1704 1690 * Mark the interfaces so that we can find phyints and prefixes
1705 1691 * which have disappeared from the kernel.
1706 1692 * if_process will set pr_in_use when it finds the
1707 1693 * interface in the kernel.
1708 1694 * Before re-examining the state of the interfaces,
1709 1695 * PI_PRESENT should be cleared from pi_kernel_state.
1710 1696 */
1711 1697 pi->pi_kernel_state &= ~PI_PRESENT;
1712 1698 for (pr = pi->pi_prefix_list; pr != NULL; pr = pr->pr_next) {
1713 1699 pr->pr_in_use = _B_FALSE;
1714 1700 }
1715 1701
1716 1702 if (ifsock < 0) {
1717 1703 ifsock = socket(AF_INET6, SOCK_DGRAM, 0);
1718 1704 if (ifsock < 0) {
1719 1705 logperror("process_rtsock: socket");
1720 1706 return;
1721 1707 }
1722 1708 }
1723 1709 if_process(ifsock, pi->pi_name, _B_FALSE);
1724 1710 for (pr = pi->pi_prefix_list; pr != NULL; pr = pr->pr_next) {
1725 1711 if_process(ifsock, pr->pr_name, _B_FALSE);
1726 1712 }
1727 1713 /*
1728 1714 * If interface (still) exists in kernel, set
1729 1715 * pi_state to indicate that.
1730 1716 */
1731 1717 if (pi->pi_kernel_state & PI_PRESENT) {
1732 1718 pi->pi_state |= PI_PRESENT;
1733 1719 }
1734 1720 check_if_removed(pi);
1735 1721 if (show_ifs)
1736 1722 phyint_print_all();
1737 1723 }
1738 1724 }
1739 1725
1740 1726 static void
1741 1727 process_mibsock(int mibsock)
1742 1728 {
1743 1729 struct phyint *pi;
1744 1730 socklen_t fromlen;
1745 1731 struct sockaddr_un from;
1746 1732 ndpd_info_t ndpd_info;
1747 1733 ssize_t len;
1748 1734 int command;
1749 1735
1750 1736 fromlen = (socklen_t)sizeof (from);
1751 1737 len = recvfrom(mibsock, &command, sizeof (int), 0,
1752 1738 (struct sockaddr *)&from, &fromlen);
1753 1739
1754 1740 if (len < sizeof (int) || command != NDPD_SNMP_INFO_REQ) {
1755 1741 logperror("process_mibsock: bad command \n");
1756 1742 return;
1757 1743 }
1758 1744
1759 1745 ndpd_info.info_type = NDPD_SNMP_INFO_RESPONSE;
1760 1746 ndpd_info.info_version = NDPD_SNMP_INFO_VER;
1761 1747 ndpd_info.info_num_of_phyints = num_of_phyints;
1762 1748
1763 1749 (void) sendto(mibsock, &ndpd_info, sizeof (ndpd_info_t), 0,
1764 1750 (struct sockaddr *)&from, fromlen);
1765 1751
1766 1752 for (pi = phyints; pi != NULL; pi = pi->pi_next) {
1767 1753 int prefixes;
1768 1754 int routers;
1769 1755 struct prefix *prefix_list;
1770 1756 struct router *router_list;
1771 1757 ndpd_phyint_info_t phyint;
1772 1758 ndpd_prefix_info_t prefix;
1773 1759 ndpd_router_info_t router;
1774 1760 /*
1775 1761 * get number of prefixes
1776 1762 */
1777 1763 routers = 0;
1778 1764 prefixes = 0;
1779 1765 prefix_list = pi->pi_prefix_list;
1780 1766 while (prefix_list != NULL) {
1781 1767 prefixes++;
1782 1768 prefix_list = prefix_list->pr_next;
1783 1769 }
1784 1770
1785 1771 /*
1786 1772 * get number of routers
1787 1773 */
1788 1774 router_list = pi->pi_router_list;
1789 1775 while (router_list != NULL) {
1790 1776 routers++;
1791 1777 router_list = router_list->dr_next;
1792 1778 }
1793 1779
1794 1780 phyint.phyint_info_type = NDPD_PHYINT_INFO;
1795 1781 phyint.phyint_info_version = NDPD_PHYINT_INFO_VER;
1796 1782 phyint.phyint_index = pi->pi_index;
1797 1783 bcopy(pi->pi_config,
1798 1784 phyint.phyint_config, I_IFSIZE);
1799 1785 phyint.phyint_num_of_prefixes = prefixes;
1800 1786 phyint.phyint_num_of_routers = routers;
1801 1787 (void) sendto(mibsock, &phyint, sizeof (phyint), 0,
1802 1788 (struct sockaddr *)&from, fromlen);
1803 1789
1804 1790 /*
1805 1791 * Copy prefix information
1806 1792 */
1807 1793
1808 1794 prefix_list = pi->pi_prefix_list;
1809 1795 while (prefix_list != NULL) {
1810 1796 prefix.prefix_info_type = NDPD_PREFIX_INFO;
1811 1797 prefix.prefix_info_version = NDPD_PREFIX_INFO_VER;
1812 1798 prefix.prefix_prefix = prefix_list->pr_prefix;
1813 1799 prefix.prefix_len = prefix_list->pr_prefix_len;
1814 1800 prefix.prefix_flags = prefix_list->pr_flags;
1815 1801 prefix.prefix_phyint_index = pi->pi_index;
1816 1802 prefix.prefix_ValidLifetime =
1817 1803 prefix_list->pr_ValidLifetime;
1818 1804 prefix.prefix_PreferredLifetime =
1819 1805 prefix_list->pr_PreferredLifetime;
1820 1806 prefix.prefix_OnLinkLifetime =
1821 1807 prefix_list->pr_OnLinkLifetime;
1822 1808 prefix.prefix_OnLinkFlag =
1823 1809 prefix_list->pr_OnLinkFlag;
1824 1810 prefix.prefix_AutonomousFlag =
1825 1811 prefix_list->pr_AutonomousFlag;
1826 1812 (void) sendto(mibsock, &prefix, sizeof (prefix), 0,
1827 1813 (struct sockaddr *)&from, fromlen);
1828 1814 prefix_list = prefix_list->pr_next;
1829 1815 }
1830 1816 /*
1831 1817 * Copy router information
1832 1818 */
1833 1819 router_list = pi->pi_router_list;
1834 1820 while (router_list != NULL) {
1835 1821 router.router_info_type = NDPD_ROUTER_INFO;
1836 1822 router.router_info_version = NDPD_ROUTER_INFO_VER;
1837 1823 router.router_address = router_list->dr_address;
1838 1824 router.router_lifetime = router_list->dr_lifetime;
1839 1825 router.router_phyint_index = pi->pi_index;
1840 1826 (void) sendto(mibsock, &router, sizeof (router), 0,
1841 1827 (struct sockaddr *)&from, fromlen);
1842 1828 router_list = router_list->dr_next;
1843 1829 }
1844 1830 }
1845 1831 }
1846 1832
1847 1833 /*
1848 1834 * Look if the phyint or one of its prefixes have been removed from
1849 1835 * the kernel and take appropriate action.
1850 1836 * Uses pr_in_use and pi{,_kernel}_state.
1851 1837 */
1852 1838 static void
1853 1839 check_if_removed(struct phyint *pi)
1854 1840 {
1855 1841 struct prefix *pr, *next_pr;
1856 1842
1857 1843 /*
1858 1844 * Detect prefixes which are removed.
1859 1845 * Static prefixes are just removed from our tables.
1860 1846 * Non-static prefixes are recreated i.e. in.ndpd takes precedence
1861 1847 * over manually removing prefixes via ifconfig.
1862 1848 */
1863 1849 for (pr = pi->pi_prefix_list; pr != NULL; pr = next_pr) {
1864 1850 next_pr = pr->pr_next;
1865 1851 if (!pr->pr_in_use) {
1866 1852 /* Clear everything except PR_STATIC */
1867 1853 pr->pr_kernel_state &= PR_STATIC;
1868 1854 if (pr->pr_state & PR_STATIC)
1869 1855 prefix_update_ipadm_addrobj(pr, _B_FALSE);
1870 1856 pr->pr_name[0] = '\0';
1871 1857 if (pr->pr_state & PR_STATIC) {
1872 1858 prefix_delete(pr);
1873 1859 } else if (!(pi->pi_kernel_state & PI_PRESENT)) {
1874 1860 /*
1875 1861 * Ensure that there are no future attempts to
1876 1862 * run prefix_update_k since the phyint is gone.
1877 1863 */
1878 1864 pr->pr_state = pr->pr_kernel_state;
1879 1865 } else if (pr->pr_state != pr->pr_kernel_state) {
1880 1866 logmsg(LOG_INFO, "Prefix manually removed "
1881 1867 "on %s; recreating\n", pi->pi_name);
1882 1868 prefix_update_k(pr);
1883 1869 }
1884 1870 }
1885 1871 }
1886 1872
1887 1873 /*
1888 1874 * Detect phyints that have been removed from the kernel, and tear
1889 1875 * down any prefixes we created that are associated with that phyint.
1890 1876 * (NOTE: IPMP depends on in.ndpd tearing down these prefixes so an
1891 1877 * administrator can easily place an IP interface with ADDRCONF'd
1892 1878 * addresses into an IPMP group.)
1893 1879 */
1894 1880 if (!(pi->pi_kernel_state & PI_PRESENT) &&
1895 1881 (pi->pi_state & PI_PRESENT)) {
1896 1882 logmsg(LOG_ERR, "Interface %s has been removed from kernel. "
1897 1883 "in.ndpd will no longer use it\n", pi->pi_name);
1898 1884
1899 1885 for (pr = pi->pi_prefix_list; pr != NULL; pr = next_pr) {
1900 1886 next_pr = pr->pr_next;
1901 1887 if (pr->pr_state & PR_AUTO)
1902 1888 prefix_update_ipadm_addrobj(pr, _B_FALSE);
1903 1889 prefix_delete(pr);
1904 1890 }
1905 1891
1906 1892 /*
1907 1893 * Clear state so that should the phyint reappear we will
1908 1894 * start with initial advertisements or solicitations.
1909 1895 */
1910 1896 phyint_cleanup(pi);
1911 1897 }
1912 1898 }
1913 1899
1914 1900
1915 1901 /*
1916 1902 * Queuing mechanism for router advertisements that are sent by in.ndpd
1917 1903 * and that also need to be processed by in.ndpd.
1918 1904 * Uses "signal number" 255 to indicate to the main poll loop
1919 1905 * that there is something to dequeue and send to incomining_ra().
1920 1906 */
1921 1907 struct raq {
1922 1908 struct raq *raq_next;
1923 1909 struct phyint *raq_pi;
1924 1910 int raq_packetlen;
1925 1911 uchar_t *raq_packet;
1926 1912 };
1927 1913 static struct raq *raq_head = NULL;
1928 1914
1929 1915 /*
1930 1916 * Allocate a struct raq and memory for the packet.
1931 1917 * Send signal 255 to have poll dequeue.
1932 1918 */
1933 1919 static void
1934 1920 loopback_ra_enqueue(struct phyint *pi, struct nd_router_advert *ra, int len)
1935 1921 {
1936 1922 struct raq *raq;
1937 1923 struct raq **raqp;
1938 1924
1939 1925 if (no_loopback)
1940 1926 return;
1941 1927
1942 1928 if (debug & D_PKTOUT)
1943 1929 logmsg(LOG_DEBUG, "loopback_ra_enqueue for %s\n", pi->pi_name);
1944 1930
1945 1931 raq = calloc(sizeof (struct raq), 1);
1946 1932 if (raq == NULL) {
1947 1933 logmsg(LOG_ERR, "loopback_ra_enqueue: out of memory\n");
1948 1934 return;
1949 1935 }
1950 1936 raq->raq_packet = malloc(len);
1951 1937 if (raq->raq_packet == NULL) {
1952 1938 free(raq);
1953 1939 logmsg(LOG_ERR, "loopback_ra_enqueue: out of memory\n");
1954 1940 return;
1955 1941 }
1956 1942 bcopy(ra, raq->raq_packet, len);
1957 1943 raq->raq_packetlen = len;
1958 1944 raq->raq_pi = pi;
1959 1945
1960 1946 /* Tail insert */
1961 1947 raqp = &raq_head;
1962 1948 while (*raqp != NULL)
1963 1949 raqp = &((*raqp)->raq_next);
1964 1950 *raqp = raq;
1965 1951
1966 1952 /* Signal for poll loop */
1967 1953 sig_handler(255);
1968 1954 }
1969 1955
1970 1956 /*
1971 1957 * Dequeue and process all queued advertisements.
1972 1958 */
1973 1959 static void
1974 1960 loopback_ra_dequeue(void)
1975 1961 {
1976 1962 struct sockaddr_in6 from = IN6ADDR_LOOPBACK_INIT;
1977 1963 struct raq *raq;
1978 1964
1979 1965 if (debug & D_PKTIN)
1980 1966 logmsg(LOG_DEBUG, "loopback_ra_dequeue()\n");
1981 1967
1982 1968 while ((raq = raq_head) != NULL) {
1983 1969 raq_head = raq->raq_next;
1984 1970 raq->raq_next = NULL;
1985 1971
1986 1972 if (debug & D_PKTIN) {
1987 1973 logmsg(LOG_DEBUG, "loopback_ra_dequeue for %s\n",
1988 1974 raq->raq_pi->pi_name);
1989 1975 }
1990 1976
1991 1977 incoming_ra(raq->raq_pi,
1992 1978 (struct nd_router_advert *)raq->raq_packet,
1993 1979 raq->raq_packetlen, &from, _B_TRUE);
1994 1980 free(raq->raq_packet);
1995 1981 free(raq);
1996 1982 }
1997 1983 }
1998 1984
1999 1985
2000 1986 static void
2001 1987 usage(char *cmd)
2002 1988 {
2003 1989 (void) fprintf(stderr,
2004 1990 "usage: %s [ -adt ] [-f <config file>]\n", cmd);
2005 1991 }
2006 1992
2007 1993 int
2008 1994 main(int argc, char *argv[])
2009 1995 {
2010 1996 int i;
2011 1997 struct phyint *pi;
2012 1998 int c;
2013 1999 char *config_file = PATH_NDPD_CONF;
2014 2000 boolean_t file_required = _B_FALSE;
2015 2001
2016 2002 argv0 = argv;
2017 2003 srandom(gethostid());
2018 2004 (void) umask(0022);
2019 2005
2020 2006 while ((c = getopt(argc, argv, "adD:ntIf:")) != EOF) {
2021 2007 switch (c) {
2022 2008 case 'a':
2023 2009 /*
2024 2010 * The StatelessAddrConf variable in ndpd.conf, if
2025 2011 * present, will override this setting.
2026 2012 */
2027 2013 ifdefaults[I_StatelessAddrConf].cf_value = 0;
2028 2014 break;
2029 2015 case 'd':
2030 2016 debug = D_ALL;
2031 2017 break;
2032 2018 case 'D':
2033 2019 i = strtol((char *)optarg, NULL, 0);
2034 2020 if (i == 0) {
2035 2021 (void) fprintf(stderr, "Bad debug flags: %s\n",
2036 2022 (char *)optarg);
2037 2023 exit(1);
2038 2024 }
2039 2025 debug |= i;
2040 2026 break;
2041 2027 case 'n':
2042 2028 no_loopback = 1;
2043 2029 break;
2044 2030 case 'I':
2045 2031 show_ifs = 1;
2046 2032 break;
2047 2033 case 't':
2048 2034 debug |= D_PKTIN | D_PKTOUT | D_PKTBAD;
2049 2035 break;
2050 2036 case 'f':
2051 2037 config_file = (char *)optarg;
2052 2038 file_required = _B_TRUE;
2053 2039 break;
2054 2040 case '?':
2055 2041 usage(argv[0]);
2056 2042 exit(1);
2057 2043 }
2058 2044 }
2059 2045
2060 2046 if (parse_config(config_file, file_required) == -1)
2061 2047 exit(2);
2062 2048
2063 2049 if (show_ifs)
2064 2050 phyint_print_all();
2065 2051
2066 2052 if (debug == 0)
2067 2053 initlog();
2068 2054
2069 2055 cmdsock = ndpd_setup_cmd_listener();
2070 2056 setup_eventpipe();
2071 2057 rtsock = setup_rtsock();
2072 2058 mibsock = setup_mibsock();
2073 2059 timer_init();
2074 2060 initifs(_B_TRUE);
2075 2061
2076 2062 check_daemonize();
2077 2063
2078 2064 for (;;) {
2079 2065 if (poll(pollfds, pollfd_num, -1) < 0) {
2080 2066 if (errno == EINTR)
2081 2067 continue;
2082 2068 logperror("main: poll");
2083 2069 exit(1);
2084 2070 }
2085 2071 for (i = 0; i < pollfd_num; i++) {
2086 2072 if (!(pollfds[i].revents & POLLIN))
2087 2073 continue;
2088 2074 if (pollfds[i].fd == eventpipe_read) {
2089 2075 in_signal(eventpipe_read);
2090 2076 break;
2091 2077 }
2092 2078 if (pollfds[i].fd == rtsock) {
2093 2079 process_rtsock(rtsock);
2094 2080 break;
2095 2081 }
2096 2082 if (pollfds[i].fd == mibsock) {
2097 2083 process_mibsock(mibsock);
2098 2084 break;
2099 2085 }
2100 2086 if (pollfds[i].fd == cmdsock) {
2101 2087 ndpd_cmd_handler(cmdsock);
2102 2088 break;
2103 2089 }
2104 2090 /*
2105 2091 * Run timer routine to advance clock if more than
2106 2092 * half a second since the clock was advanced.
2107 2093 * This limits CPU usage under severe packet
2108 2094 * arrival rates but it creates a slight inaccuracy
2109 2095 * in the timer mechanism.
2110 2096 */
2111 2097 conditional_run_timeouts(500U);
2112 2098 for (pi = phyints; pi != NULL; pi = pi->pi_next) {
2113 2099 if (pollfds[i].fd == pi->pi_sock) {
2114 2100 in_data(pi);
2115 2101 break;
2116 2102 }
2117 2103 }
2118 2104 }
2119 2105 }
2120 2106 /* NOTREACHED */
2121 2107 return (0);
2122 2108 }
2123 2109
2124 2110 /*
2125 2111 * LOGGER
2126 2112 */
2127 2113
2128 2114 static boolean_t logging = _B_FALSE;
2129 2115
2130 2116 static void
2131 2117 initlog(void)
2132 2118 {
2133 2119 logging = _B_TRUE;
2134 2120 openlog("in.ndpd", LOG_PID | LOG_CONS, LOG_DAEMON);
2135 2121 }
2136 2122
2137 2123 /* Print the date/time without a trailing carridge return */
2138 2124 static void
2139 2125 fprintdate(FILE *file)
2140 2126 {
2141 2127 char buf[BUFSIZ];
2142 2128 struct tm tms;
2143 2129 time_t now;
2144 2130
2145 2131 now = time(NULL);
2146 2132 (void) localtime_r(&now, &tms);
2147 2133 (void) strftime(buf, sizeof (buf), "%h %d %X", &tms);
2148 2134 (void) fprintf(file, "%s ", buf);
2149 2135 }
2150 2136
2151 2137 /* PRINTFLIKE2 */
2152 2138 void
2153 2139 logmsg(int level, const char *fmt, ...)
2154 2140 {
2155 2141 va_list ap;
2156 2142 va_start(ap, fmt);
2157 2143
2158 2144 if (logging) {
2159 2145 vsyslog(level, fmt, ap);
2160 2146 } else {
2161 2147 fprintdate(stderr);
2162 2148 (void) vfprintf(stderr, fmt, ap);
2163 2149 }
2164 2150 va_end(ap);
2165 2151 }
2166 2152
2167 2153 void
2168 2154 logperror(const char *str)
2169 2155 {
2170 2156 if (logging) {
2171 2157 syslog(LOG_ERR, "%s: %m\n", str);
2172 2158 } else {
2173 2159 fprintdate(stderr);
2174 2160 (void) fprintf(stderr, "%s: %s\n", str, strerror(errno));
2175 2161 }
2176 2162 }
2177 2163
2178 2164 void
2179 2165 logperror_pi(const struct phyint *pi, const char *str)
2180 2166 {
2181 2167 if (logging) {
2182 2168 syslog(LOG_ERR, "%s (interface %s): %m\n",
2183 2169 str, pi->pi_name);
2184 2170 } else {
2185 2171 fprintdate(stderr);
2186 2172 (void) fprintf(stderr, "%s (interface %s): %s\n",
2187 2173 str, pi->pi_name, strerror(errno));
2188 2174 }
2189 2175 }
2190 2176
2191 2177 void
2192 2178 logperror_pr(const struct prefix *pr, const char *str)
2193 2179 {
2194 2180 if (logging) {
2195 2181 syslog(LOG_ERR, "%s (prefix %s if %s): %m\n",
2196 2182 str, pr->pr_name, pr->pr_physical->pi_name);
2197 2183 } else {
2198 2184 fprintdate(stderr);
2199 2185 (void) fprintf(stderr, "%s (prefix %s if %s): %s\n",
2200 2186 str, pr->pr_name, pr->pr_physical->pi_name,
2201 2187 strerror(errno));
2202 2188 }
2203 2189 }
2204 2190
2205 2191 static int
2206 2192 ndpd_setup_cmd_listener(void)
2207 2193 {
2208 2194 int sock;
2209 2195 int ret;
2210 2196 struct sockaddr_un servaddr;
2211 2197
2212 2198 sock = socket(AF_UNIX, SOCK_STREAM, 0);
2213 2199 if (sock < 0) {
2214 2200 logperror("socket");
2215 2201 exit(1);
2216 2202 }
2217 2203
2218 2204 bzero(&servaddr, sizeof (servaddr));
2219 2205 servaddr.sun_family = AF_UNIX;
2220 2206 (void) strlcpy(servaddr.sun_path, IPADM_UDS_PATH,
2221 2207 sizeof (servaddr.sun_path));
2222 2208 (void) unlink(servaddr.sun_path);
2223 2209 ret = bind(sock, (struct sockaddr *)&servaddr, sizeof (servaddr));
2224 2210 if (ret < 0) {
2225 2211 logperror("bind");
2226 2212 exit(1);
2227 2213 }
2228 2214 if (listen(sock, 30) < 0) {
2229 2215 logperror("listen");
2230 2216 exit(1);
2231 2217 }
2232 2218 if (poll_add(sock) == -1) {
2233 2219 logmsg(LOG_ERR, "command socket could not be added to the "
2234 2220 "polling set\n");
2235 2221 exit(1);
2236 2222 }
2237 2223
2238 2224 return (sock);
2239 2225 }
2240 2226
2241 2227 /*
2242 2228 * Commands received over the command socket come here
2243 2229 */
2244 2230 static void
2245 2231 ndpd_cmd_handler(int sock)
2246 2232 {
2247 2233 int newfd;
2248 2234 struct sockaddr_storage peer;
2249 2235 socklen_t peerlen;
2250 2236 ipadm_ndpd_msg_t ndpd_msg;
2251 2237 int retval;
2252 2238
2253 2239 peerlen = sizeof (peer);
2254 2240 newfd = accept(sock, (struct sockaddr *)&peer, &peerlen);
2255 2241 if (newfd < 0) {
2256 2242 logperror("accept");
2257 2243 return;
2258 2244 }
2259 2245
2260 2246 retval = ipadm_ndpd_read(newfd, &ndpd_msg, sizeof (ndpd_msg));
2261 2247 if (retval != 0)
2262 2248 logperror("Could not read ndpd command");
2263 2249
2264 2250 retval = ndpd_process_cmd(newfd, &ndpd_msg);
2265 2251 if (retval != 0) {
2266 2252 logmsg(LOG_ERR, "ndpd command on interface %s failed with "
2267 2253 "error %s\n", ndpd_msg.inm_ifname, strerror(retval));
2268 2254 }
2269 2255 (void) close(newfd);
2270 2256 }
2271 2257
2272 2258 /*
2273 2259 * Process the commands received from the cmd listener socket.
2274 2260 */
2275 2261 static int
2276 2262 ndpd_process_cmd(int newfd, ipadm_ndpd_msg_t *msg)
2277 2263 {
2278 2264 int err;
2279 2265
2280 2266 if (!ipadm_check_auth()) {
2281 2267 logmsg(LOG_ERR, "User not authorized to send the command\n");
2282 2268 (void) ndpd_send_error(newfd, EPERM);
2283 2269 return (EPERM);
2284 2270 }
2285 2271 switch (msg->inm_cmd) {
2286 2272 case IPADM_DISABLE_AUTOCONF:
2287 2273 err = ndpd_set_autoconf(msg->inm_ifname, _B_FALSE);
2288 2274 break;
2289 2275
2290 2276 case IPADM_ENABLE_AUTOCONF:
2291 2277 err = ndpd_set_autoconf(msg->inm_ifname, _B_TRUE);
2292 2278 break;
2293 2279
2294 2280 case IPADM_CREATE_ADDRS:
2295 2281 err = ndpd_create_addrs(msg->inm_ifname, msg->inm_intfid,
2296 2282 msg->inm_intfidlen, msg->inm_stateless,
2297 2283 msg->inm_stateful, msg->inm_aobjname);
2298 2284 break;
2299 2285
2300 2286 case IPADM_DELETE_ADDRS:
2301 2287 err = ndpd_delete_addrs(msg->inm_ifname);
2302 2288 break;
2303 2289
2304 2290 default:
2305 2291 err = EINVAL;
2306 2292 break;
2307 2293 }
2308 2294
2309 2295 (void) ndpd_send_error(newfd, err);
2310 2296
2311 2297 return (err);
2312 2298 }
2313 2299
2314 2300 static int
2315 2301 ndpd_send_error(int fd, int error)
2316 2302 {
2317 2303 return (ipadm_ndpd_write(fd, &error, sizeof (error)));
2318 2304 }
2319 2305
2320 2306 /*
2321 2307 * Disables/Enables autoconfiguration of addresses on the
2322 2308 * given physical interface.
2323 2309 * This is provided to support the legacy method of configuring IPv6
2324 2310 * addresses. i.e. `ifconfig bge0 inet6 plumb` will plumb the interface
2325 2311 * and start stateless and stateful autoconfiguration. If this function is
2326 2312 * not called with enable=_B_FALSE, no autoconfiguration will be done until
2327 2313 * ndpd_create_addrs() is called with an Interface ID.
2328 2314 */
2329 2315 static int
2330 2316 ndpd_set_autoconf(const char *ifname, boolean_t enable)
2331 2317 {
2332 2318 struct phyint *pi;
2333 2319
2334 2320 pi = phyint_lookup((char *)ifname);
2335 2321 if (pi == NULL) {
2336 2322 /*
2337 2323 * If the physical interface was plumbed but no
2338 2324 * addresses were configured yet, phyint will not exist.
2339 2325 */
2340 2326 pi = phyint_create((char *)ifname);
2341 2327 if (pi == NULL) {
2342 2328 logmsg(LOG_ERR, "could not create phyint for "
2343 2329 "interface %s", ifname);
2344 2330 return (ENOMEM);
2345 2331 }
2346 2332 }
2347 2333 pi->pi_autoconf = enable;
2348 2334
2349 2335 if (debug & D_PHYINT) {
2350 2336 logmsg(LOG_DEBUG, "ndpd_set_autoconf: %s autoconf for "
2351 2337 "interface %s\n", (enable ? "enabled" : "disabled"),
2352 2338 pi->pi_name);
2353 2339 }
2354 2340 return (0);
2355 2341 }
2356 2342
2357 2343 /*
2358 2344 * Create auto-configured addresses on the given interface using
2359 2345 * the given token as the interface id during the next Router Advertisement.
2360 2346 * Currently, only one token per interface is supported.
2361 2347 */
2362 2348 static int
2363 2349 ndpd_create_addrs(const char *ifname, struct sockaddr_in6 intfid, int intfidlen,
2364 2350 boolean_t stateless, boolean_t stateful, char *addrobj)
2365 2351 {
2366 2352 struct phyint *pi;
2367 2353 struct lifreq lifr;
2368 2354 struct sockaddr_in6 *sin6;
2369 2355 int err;
2370 2356
2371 2357 pi = phyint_lookup((char *)ifname);
2372 2358 if (pi == NULL) {
2373 2359 /*
2374 2360 * If the physical interface was plumbed but no
2375 2361 * addresses were configured yet, phyint will not exist.
2376 2362 */
2377 2363 pi = phyint_create((char *)ifname);
2378 2364 if (pi == NULL) {
2379 2365 if (debug & D_PHYINT)
2380 2366 logmsg(LOG_ERR, "could not create phyint "
2381 2367 "for interface %s", ifname);
2382 2368 return (ENOMEM);
2383 2369 }
2384 2370 } else if (pi->pi_autoconf) {
2385 2371 logmsg(LOG_ERR, "autoconfiguration already in progress\n");
2386 2372 return (EEXIST);
2387 2373 }
2388 2374 check_autoconf_var_consistency(pi, stateless, stateful);
2389 2375
2390 2376 if (intfidlen == 0) {
2391 2377 pi->pi_default_token = _B_TRUE;
2392 2378 if (ifsock < 0) {
2393 2379 ifsock = socket(AF_INET6, SOCK_DGRAM, 0);
2394 2380 if (ifsock < 0) {
2395 2381 err = errno;
2396 2382 logperror("ndpd_create_addrs: socket");
2397 2383 return (err);
2398 2384 }
2399 2385 }
2400 2386 (void) strncpy(lifr.lifr_name, ifname, sizeof (lifr.lifr_name));
2401 2387 sin6 = (struct sockaddr_in6 *)&lifr.lifr_addr;
2402 2388 if (ioctl(ifsock, SIOCGLIFTOKEN, (char *)&lifr) < 0) {
2403 2389 err = errno;
2404 2390 logperror("SIOCGLIFTOKEN");
2405 2391 return (err);
2406 2392 }
2407 2393 pi->pi_token = sin6->sin6_addr;
2408 2394 pi->pi_token_length = lifr.lifr_addrlen;
2409 2395 } else {
2410 2396 pi->pi_default_token = _B_FALSE;
2411 2397 pi->pi_token = intfid.sin6_addr;
2412 2398 pi->pi_token_length = intfidlen;
2413 2399 }
2414 2400 pi->pi_stateless = stateless;
2415 2401 pi->pi_stateful = stateful;
2416 2402 (void) strlcpy(pi->pi_ipadm_aobjname, addrobj,
2417 2403 sizeof (pi->pi_ipadm_aobjname));
2418 2404
2419 2405 /* We can allow autoconfiguration now. */
2420 2406 pi->pi_autoconf = _B_TRUE;
2421 2407
2422 2408 /* Restart the solicitations. */
2423 2409 if (pi->pi_sol_state == DONE_SOLICIT)
2424 2410 pi->pi_sol_state = NO_SOLICIT;
2425 2411 if (pi->pi_sol_state == NO_SOLICIT)
2426 2412 check_to_solicit(pi, START_INIT_SOLICIT);
2427 2413 if (debug & D_PHYINT)
2428 2414 logmsg(LOG_DEBUG, "ndpd_create_addrs: "
2429 2415 "added token to interface %s\n", pi->pi_name);
2430 2416 return (0);
2431 2417 }
2432 2418
2433 2419 /*
2434 2420 * This function deletes all addresses on the given interface
2435 2421 * with the given Interface ID.
2436 2422 */
2437 2423 static int
2438 2424 ndpd_delete_addrs(const char *ifname)
2439 2425 {
2440 2426 struct phyint *pi;
2441 2427 struct prefix *pr, *next_pr;
2442 2428 struct lifreq lifr;
2443 2429 int err;
2444 2430
2445 2431 pi = phyint_lookup((char *)ifname);
2446 2432 if (pi == NULL) {
2447 2433 logmsg(LOG_ERR, "no phyint found for %s", ifname);
2448 2434 return (ENXIO);
2449 2435 }
2450 2436 if (IN6_IS_ADDR_UNSPECIFIED(&pi->pi_token)) {
2451 2437 logmsg(LOG_ERR, "token does not exist for %s", ifname);
2452 2438 return (EINVAL);
2453 2439 }
2454 2440
2455 2441 if (ifsock < 0) {
2456 2442 ifsock = socket(AF_INET6, SOCK_DGRAM, 0);
2457 2443 if (ifsock < 0) {
2458 2444 err = errno;
2459 2445 logperror("ndpd_create_addrs: socket");
2460 2446 return (err);
2461 2447 }
2462 2448 }
2463 2449 /* Remove the prefixes for this phyint if they exist */
2464 2450 for (pr = pi->pi_prefix_list; pr != NULL; pr = next_pr) {
2465 2451 next_pr = pr->pr_next;
2466 2452 if (pr->pr_name[0] == '\0') {
2467 2453 prefix_delete(pr);
2468 2454 continue;
2469 2455 }
2470 2456 /*
2471 2457 * Delete all the prefixes for the auto-configured
2472 2458 * addresses as well as the DHCPv6 addresses.
2473 2459 */
2474 2460 (void) strncpy(lifr.lifr_name, pr->pr_name,
2475 2461 sizeof (lifr.lifr_name));
2476 2462 if (ioctl(ifsock, SIOCGLIFFLAGS, (char *)&lifr) < 0) {
2477 2463 err = errno;
2478 2464 logperror("SIOCGLIFFLAGS");
2479 2465 return (err);
2480 2466 }
2481 2467 if ((lifr.lifr_flags & IFF_ADDRCONF) ||
2482 2468 (lifr.lifr_flags & IFF_DHCPRUNNING)) {
2483 2469 prefix_update_ipadm_addrobj(pr, _B_FALSE);
2484 2470 }
2485 2471 prefix_delete(pr);
2486 2472 }
2487 2473
2488 2474 /*
2489 2475 * If we had started dhcpagent, we need to release the leases
2490 2476 * if any are required.
2491 2477 */
2492 2478 if (pi->pi_stateful) {
2493 2479 (void) strncpy(lifr.lifr_name, pi->pi_name,
2494 2480 sizeof (lifr.lifr_name));
2495 2481 if (ioctl(ifsock, SIOCGLIFFLAGS, (char *)&lifr) < 0) {
2496 2482 err = errno;
2497 2483 logperror("SIOCGLIFFLAGS");
2498 2484 return (err);
2499 2485 }
2500 2486 if (lifr.lifr_flags & IFF_DHCPRUNNING)
2501 2487 release_dhcp(pi);
2502 2488 }
2503 2489
2504 2490 /*
2505 2491 * Reset the Interface ID on this phyint and stop autoconfigurations
2506 2492 * until a new interface ID is provided.
2507 2493 */
2508 2494 pi->pi_token = in6addr_any;
2509 2495 pi->pi_token_length = 0;
2510 2496 pi->pi_autoconf = _B_FALSE;
2511 2497 pi->pi_ipadm_aobjname[0] = '\0';
2512 2498
2513 2499 /* Reset the stateless and stateful settings to default. */
2514 2500 pi->pi_stateless = pi->pi_StatelessAddrConf;
2515 2501 pi->pi_stateful = pi->pi_StatefulAddrConf;
2516 2502
2517 2503 if (debug & D_PHYINT) {
2518 2504 logmsg(LOG_DEBUG, "ndpd_delete_addrs: "
2519 2505 "removed token from interface %s\n", pi->pi_name);
2520 2506 }
2521 2507 return (0);
2522 2508 }
2523 2509
2524 2510 void
2525 2511 check_autoconf_var_consistency(struct phyint *pi, boolean_t stateless,
2526 2512 boolean_t stateful)
2527 2513 {
2528 2514 /*
2529 2515 * If StatelessAddrConf and StatelessAddrConf are set in
2530 2516 * /etc/inet/ndpd.conf, check if the new values override those
2531 2517 * settings. If so, log a warning.
2532 2518 */
2533 2519 if ((pi->pi_StatelessAddrConf !=
2534 2520 ifdefaults[I_StatelessAddrConf].cf_value &&
2535 2521 stateless != pi->pi_StatelessAddrConf) ||
2536 2522 (pi->pi_StatefulAddrConf !=
2537 2523 ifdefaults[I_StatefulAddrConf].cf_value &&
2538 2524 stateful != pi->pi_StatefulAddrConf)) {
2539 2525 logmsg(LOG_ERR, "check_autoconf_var_consistency: "
2540 2526 "Overriding the StatelessAddrConf or StatefulAddrConf "
2541 2527 "settings in ndpd.conf with the new values for "
2542 2528 "interface %s\n", pi->pi_name);
2543 2529 }
2544 2530 }
2545 2531
2546 2532 /*
2547 2533 * If ipadm was used to start autoconfiguration and in.ndpd was restarted
2548 2534 * for some reason, in.ndpd has to resume autoconfiguration when it comes up.
2549 2535 * In this function, it scans the ipadm_addr_info() output to find a link-local
2550 2536 * on this interface with address type "addrconf" and extracts the interface id.
2551 2537 * It also stores the addrobj name to be used later when new addresses are
2552 2538 * created for the prefixes advertised by the router.
2553 2539 * If autoconfiguration was never started on this interface before in.ndpd
2554 2540 * was killed, then in.ndpd should refrain from configuring prefixes, even if
2555 2541 * there is a valid link-local on this interface, created by ipadm (identified
2556 2542 * if there is a valid addrobj name).
2557 2543 */
2558 2544 static int
2559 2545 phyint_check_ipadm_intfid(struct phyint *pi)
2560 2546 {
2561 2547 ipadm_status_t status;
2562 2548 ipadm_addr_info_t *addrinfo;
2563 2549 struct ifaddrs *ifap;
2564 2550 ipadm_addr_info_t *ainfop;
2565 2551 struct sockaddr_in6 *sin6;
2566 2552 ipadm_handle_t iph;
2567 2553
2568 2554 if (ipadm_open(&iph, 0) != IPADM_SUCCESS) {
2569 2555 logmsg(LOG_ERR, "could not open handle to libipadm\n");
2570 2556 return (-1);
2571 2557 }
2572 2558
2573 2559 status = ipadm_addr_info(iph, pi->pi_name, &addrinfo,
2574 2560 IPADM_OPT_ZEROADDR, LIFC_NOXMIT|LIFC_TEMPORARY);
2575 2561 if (status != IPADM_SUCCESS) {
2576 2562 ipadm_close(iph);
2577 2563 return (-1);
2578 2564 }
2579 2565 pi->pi_autoconf = _B_TRUE;
2580 2566 for (ainfop = addrinfo; ainfop != NULL; ainfop = IA_NEXT(ainfop)) {
2581 2567 ifap = &ainfop->ia_ifa;
2582 2568 if (ifap->ifa_addr->sa_family != AF_INET6 ||
2583 2569 ainfop->ia_state == IFA_DISABLED)
2584 2570 continue;
2585 2571 sin6 = (struct sockaddr_in6 *)ifap->ifa_addr;
2586 2572 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
2587 2573 if (ainfop->ia_atype == IPADM_ADDR_IPV6_ADDRCONF) {
2588 2574 pi->pi_token = sin6->sin6_addr;
2589 2575 pi->pi_token._S6_un._S6_u32[0] = 0;
2590 2576 pi->pi_token._S6_un._S6_u32[1] = 0;
2591 2577 pi->pi_autoconf = _B_TRUE;
2592 2578 (void) strlcpy(pi->pi_ipadm_aobjname,
2593 2579 ainfop->ia_aobjname,
2594 2580 sizeof (pi->pi_ipadm_aobjname));
2595 2581 break;
2596 2582 }
2597 2583 /*
2598 2584 * If IFF_NOLINKLOCAL is set, then the link-local
2599 2585 * was created using ipadm. Do not autoconfigure until
2600 2586 * ipadm is explicitly used for autoconfiguration.
2601 2587 */
2602 2588 if (ifap->ifa_flags & IFF_NOLINKLOCAL)
2603 2589 pi->pi_autoconf = _B_FALSE;
2604 2590 } else if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) &&
2605 2591 strrchr(ifap->ifa_name, ':') == NULL) {
2606 2592 /* The interface was created using ipadm. */
2607 2593 pi->pi_autoconf = _B_FALSE;
2608 2594 }
2609 2595 }
2610 2596 ipadm_free_addr_info(addrinfo);
2611 2597 if (!pi->pi_autoconf) {
2612 2598 pi->pi_token = in6addr_any;
2613 2599 pi->pi_token_length = 0;
2614 2600 }
2615 2601 ipadm_close(iph);
2616 2602 return (0);
2617 2603 }
↓ open down ↓ |
1647 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX