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