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