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