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