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.
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.
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]
21 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
29 static void initlog(void);
30 static void run_timeouts(void);
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);
42 struct in6_addr all_nodes_mcast
= { { 0xff, 0x2, 0x0, 0x0,
45 0x0, 0x0, 0x0, 0x1 } };
47 struct in6_addr all_routers_mcast
= { { 0xff, 0x2, 0x0, 0x0,
50 0x0, 0x0, 0x0, 0x2 } };
52 static struct sockaddr_in6 v6allnodes
= { AF_INET6
, 0, 0,
53 { 0xff, 0x2, 0x0, 0x0,
56 0x0, 0x0, 0x0, 0x1 } };
58 static struct sockaddr_in6 v6allrouters
= { AF_INET6
, 0, 0,
59 { 0xff, 0x2, 0x0, 0x0,
62 0x0, 0x0, 0x0, 0x2 } };
64 static char **argv0
; /* Saved for re-exec on SIGHUP */
66 static uint64_t packet
[(IP_MAXPACKET
+ 1)/8];
68 static int show_ifs
= 0;
69 static boolean_t already_daemonized
= _B_FALSE
;
71 int no_loopback
= 0; /* Do not send RA packets to ourselves */
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).
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)
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
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 */
95 * These sockets are used internally in this file.
97 static int mibsock
= -1; /* mib request socket */
98 static int cmdsock
= -1; /* command socket */
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
*);
111 * Return the current time in milliseconds truncated to
119 if (gettimeofday(&tp
, NULL
) < 0) {
120 logperror("getcurrenttime: gettimeofday failed");
123 return (tp
.tv_sec
* 1000 + tp
.tv_usec
/ 1000);
127 * Output a preformated packet from the packet[] buffer.
130 sendpacket(struct sockaddr_in6
*sin6
, int sock
, int size
, int flags
)
133 char abuf
[INET6_ADDRSTRLEN
];
135 cc
= sendto(sock
, (char *)packet
, size
, flags
,
136 (struct sockaddr
*)sin6
, sizeof (*sin6
));
137 if (cc
< 0 || cc
!= size
) {
139 logperror("sendpacket: sendto");
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
)),
150 * If possible, place an ND_OPT_SOURCE_LINKADDR option at `optp'.
151 * Return the number of bytes placed in the option.
154 add_opt_lla(struct phyint
*pi
, struct nd_opt_lla
*optp
)
160 /* If this phyint doesn't have a link-layer address, bail */
161 if (phyint_get_lla(pi
, &lifr
) == -1)
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;
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
);
175 /* Send a Router Solicitation */
177 solicit(struct sockaddr_in6
*sin6
, struct phyint
*pi
)
180 struct nd_router_solicit
*rs
= (struct nd_router_solicit
*)packet
;
181 char *pptr
= (char *)packet
;
183 rs
->nd_rs_type
= ND_ROUTER_SOLICIT
;
185 rs
->nd_rs_cksum
= htons(0);
186 rs
->nd_rs_reserved
= htonl(0);
188 packetlen
+= sizeof (*rs
);
189 pptr
+= sizeof (*rs
);
192 packetlen
+= add_opt_lla(pi
, (struct nd_opt_lla
*)pptr
);
194 if (debug
& D_PKTOUT
) {
195 print_route_sol("Sending solicitation to ", pi
, rs
, packetlen
,
198 sendpacket(sin6
, pi
->pi_sock
, packetlen
, 0);
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.
208 advertise(struct sockaddr_in6
*sin6
, struct phyint
*pi
, boolean_t no_prefixes
)
210 struct nd_opt_prefix_info
*po
;
211 char *pptr
= (char *)packet
;
212 struct nd_router_advert
*ra
;
213 struct adv_prefix
*adv_pr
;
216 ra
= (struct nd_router_advert
*)pptr
;
217 ra
->nd_ra_type
= ND_ROUTER_ADVERT
;
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
;
227 if (pi
->pi_adv_state
== FINAL_ADV
)
228 ra
->nd_ra_router_lifetime
= htons(0);
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
);
234 packetlen
= sizeof (*ra
);
235 pptr
+= sizeof (*ra
);
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
);
242 sendpacket(sin6
, pi
->pi_sock
, packetlen
, 0);
243 /* Feed packet back in for router operation */
244 loopback_ra_enqueue(pi
, ra
, packetlen
);
249 packetlen
+= add_opt_lla(pi
, (struct nd_opt_lla
*)pptr
);
250 pptr
= (char *)packet
+ packetlen
;
252 if (pi
->pi_AdvLinkMTU
!= 0) {
253 struct nd_opt_mtu
*mo
= (struct nd_opt_mtu
*)pptr
;
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
);
260 packetlen
+= sizeof (struct nd_opt_mtu
);
261 pptr
+= sizeof (struct nd_opt_mtu
);
265 if (debug
& D_PKTOUT
) {
266 print_route_adv("Sending advert to ", pi
,
267 ra
, packetlen
, sin6
);
269 sendpacket(sin6
, pi
->pi_sock
, packetlen
, 0);
270 /* Feed packet back in for router operation */
271 loopback_ra_enqueue(pi
, ra
, packetlen
);
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
) {
284 * If the prefix doesn't fit in packet send
285 * what we have so far and start with new packet.
287 if (packetlen
+ sizeof (*po
) >
288 pi
->pi_LinkMTU
- sizeof (struct ip6_hdr
)) {
289 if (debug
& D_PKTOUT
) {
290 print_route_adv("Sending advert "
292 pi
, ra
, packetlen
, sin6
);
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
;
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
;
308 if (adv_pr
->adv_pr_AdvAutonomousFlag
) {
309 po
->nd_opt_pi_flags_reserved
|=
312 po
->nd_opt_pi_prefix_len
= adv_pr
->adv_pr_prefix_len
;
314 * If both Adv*Expiration and Adv*Lifetime are
315 * set we prefer the former and make the lifetime
316 * decrement in real time.
318 if (adv_pr
->adv_pr_AdvValidRealTime
) {
319 po
->nd_opt_pi_valid_time
=
320 htonl(adv_pr
->adv_pr_AdvValidExpiration
);
322 po
->nd_opt_pi_valid_time
=
323 htonl(adv_pr
->adv_pr_AdvValidLifetime
);
325 if (adv_pr
->adv_pr_AdvPreferredRealTime
) {
326 po
->nd_opt_pi_preferred_time
=
327 htonl(adv_pr
->adv_pr_AdvPreferredExpiration
);
329 po
->nd_opt_pi_preferred_time
=
330 htonl(adv_pr
->adv_pr_AdvPreferredLifetime
);
332 po
->nd_opt_pi_reserved2
= htonl(0);
333 po
->nd_opt_pi_prefix
= adv_pr
->adv_pr_prefix
;
336 packetlen
+= sizeof (*po
);
338 if (debug
& D_PKTOUT
) {
339 print_route_adv("Sending advert to ", pi
,
340 ra
, packetlen
, sin6
);
342 sendpacket(sin6
, pi
->pi_sock
, packetlen
, 0);
343 /* Feed packet back in for router operation */
344 loopback_ra_enqueue(pi
, ra
, packetlen
);
348 static int pollfd_num
= 0; /* Allocated and initialized */
349 static struct pollfd
*pollfds
= NULL
;
352 * Add fd to the set being polled. Returns 0 if ok; -1 if failed.
359 struct pollfd
*newfds
;
361 /* Check if already present */
362 for (i
= 0; i
< pollfd_num
; i
++) {
363 if (pollfds
[i
].fd
== fd
)
366 /* Check for empty spot already present */
367 for (i
= 0; i
< pollfd_num
; i
++) {
368 if (pollfds
[i
].fd
== -1) {
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");
382 newfds
[pollfd_num
].fd
= fd
;
383 newfds
[pollfd_num
++].events
= POLLIN
;
385 for (i
= pollfd_num
; i
< new_num
; i
++) {
387 newfds
[i
].events
= POLLIN
;
389 pollfd_num
= new_num
;
395 * Remove fd from the set being polled. Returns 0 if ok; -1 if failed.
402 /* Check if already present */
403 for (i
= 0; i
< pollfd_num
; i
++) {
404 if (pollfds
[i
].fd
== fd
) {
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
421 if_process(int s
, char *ifname
, boolean_t first
)
427 char phyintname
[LIFNAMSIZ
+ 1];
429 if (debug
& D_IFSCAN
)
430 logmsg(LOG_DEBUG
, "if_process(%s)\n", ifname
);
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
) {
437 * Interface has disappeared
441 logperror("if_process: ioctl (get interface flags)");
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.
450 if (!(lifr
.lifr_flags
& IFF_MULTICAST
) ||
451 (lifr
.lifr_flags
& (IFF_LOOPBACK
|IFF_VRRP
))) {
455 if (!(lifr
.lifr_flags
& IFF_IPV6
))
458 (void) strncpy(phyintname
, ifname
, sizeof (phyintname
));
459 phyintname
[sizeof (phyintname
) - 1] = '\0';
460 if ((cp
= strchr(phyintname
, IF_SEPARATOR
)) != NULL
) {
464 pi
= phyint_lookup(phyintname
);
466 pi
= phyint_create(phyintname
);
468 logmsg(LOG_ERR
, "if_process: out of memory\n");
472 * if in.ndpd is restarted, check with ipmgmtd if there is any
473 * interface id to be configured for this interface.
476 if (phyint_check_ipadm_intfid(pi
) == -1)
477 logmsg(LOG_ERR
, "Could not get ipadm info\n");
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().
485 (void) phyint_init_from_k(pi
);
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
);
496 if (pi
->pi_sock
!= -1) {
497 if (poll_add(pi
->pi_sock
) == -1) {
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.
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
);
517 pi
->pi_AdvSendAdvertisements
= 0;
518 pi
->pi_sol_state
= NO_SOLICIT
;
522 * Send advertisments and solicitation only if the interface is
523 * present in the kernel.
525 if (pi
->pi_kernel_state
& PI_PRESENT
) {
527 if (pi
->pi_AdvSendAdvertisements
) {
528 if (pi
->pi_adv_state
== NO_ADV
)
529 check_to_advertise(pi
, START_INIT_ADV
);
531 if (pi
->pi_sol_state
== NO_SOLICIT
)
532 check_to_solicit(pi
, START_INIT_SOLICIT
);
537 * Track static kernel prefixes to prevent in.ndpd from clobbering
538 * them by creating a struct prefix for each prefix detected in the
541 pr
= prefix_lookup_name(pi
, ifname
);
543 pr
= prefix_create_name(pi
, ifname
);
545 logmsg(LOG_ERR
, "if_process: out of memory\n");
548 if (prefix_init_from_k(pr
) == -1) {
553 /* Detect prefixes which are removed */
554 if (pr
->pr_kernel_state
!= 0)
555 pr
->pr_in_use
= _B_TRUE
;
557 if ((lifr
.lifr_flags
& IFF_DUPLICATE
) &&
558 !(lifr
.lifr_flags
& IFF_DHCPRUNNING
) &&
559 (pr
->pr_flags
& IFF_TEMPORARY
)) {
562 char abuf
[INET6_ADDRSTRLEN
];
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;
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
)) {
582 token
= &pi
->pi_tmp_token
;
583 for (i
= 0; i
< 16; i
++) {
585 * prefix_create ensures that pr_prefix has all-zero
586 * bits after prefixlen.
588 pr
->pr_address
.s6_addr
[i
] = pr
->pr_prefix
.s6_addr
[i
] |
591 if (prefix_lookup_addr_match(pr
) != NULL
) {
595 pr
->pr_CreateTime
= getcurrenttime() / MILLISEC
;
597 * We've got a new token. Clearing PR_AUTO causes
598 * prefix_update_k to bring the interface up and set the
601 pr
->pr_kernel_state
&= ~PR_AUTO
;
606 static int ifsock
= -1;
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.
613 initifs(boolean_t first
)
623 struct phyint
*next_pi
;
626 if (debug
& D_IFSCAN
)
627 logmsg(LOG_DEBUG
, "Reading interface configuration\n");
629 ifsock
= socket(AF_INET6
, SOCK_DGRAM
, 0);
631 logperror("initifs: socket");
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)");
641 numifs
= lifn
.lifn_count
;
642 bufsize
= numifs
* sizeof (struct lifreq
);
644 buf
= (char *)malloc(bufsize
);
646 logmsg(LOG_ERR
, "initifs: out of memory\n");
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
656 for (pi
= phyints
; pi
!= NULL
; pi
= pi
->pi_next
) {
658 * Before re-examining the state of the interfaces,
659 * PI_PRESENT should be cleared from pi_kernel_state.
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
;
667 lifc
.lifc_family
= AF_INET6
;
668 lifc
.lifc_flags
= LIFC_NOXMIT
| LIFC_TEMPORARY
;
669 lifc
.lifc_len
= bufsize
;
672 if (ioctl(ifsock
, SIOCGLIFCONF
, (char *)&lifc
) < 0) {
673 logperror("initifs: ioctl (get interface configuration)");
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
);
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.
688 for (pi
= phyints
; pi
!= NULL
; pi
= next_pi
) {
689 next_pi
= pi
->pi_next
;
691 * If interface (still) exists in kernel, set
692 * pi_state to indicate that.
694 if (pi
->pi_kernel_state
& PI_PRESENT
) {
695 pi
->pi_state
|= PI_PRESENT
;
698 check_if_removed(pi
);
706 * Router advertisement state machine. Used for everything but timer
707 * events which use advertise_event directly.
710 check_to_advertise(struct phyint
*pi
, enum adv_events event
)
713 enum adv_states old_state
= pi
->pi_adv_state
;
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
);
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
);
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
);
733 * Router advertisement state machine.
734 * Return the number of milliseconds until next timeout (TIMER_INFINITY
736 * For the ADV_TIMER event the caller passes in the number of milliseconds
737 * since the last timer event in the 'elapsed' parameter.
740 advertise_event(struct phyint
*pi
, enum adv_events event
, uint_t elapsed
)
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
);
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",
757 return (TIMER_INFINITY
);
762 pi
->pi_adv_state
= NO_ADV
;
763 return (TIMER_INFINITY
);
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 */
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 */
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
);
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
) {
796 * Send an advertisement (ND_MIN_DELAY_BETWEEN_RAS
797 * plus random delay) after the previous
798 * advertisement was sent.
800 pi
->pi_adv_time_left
= delay
+
801 ND_MIN_DELAY_BETWEEN_RAS
-
802 pi
->pi_adv_time_since_sent
;
804 pi
->pi_adv_state
= SOLICIT_ADV
;
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
;
814 pi
->pi_adv_time_left
= 0;
816 /* Increase time since last advertisement was sent */
817 pi
->pi_adv_time_since_sent
+= elapsed
;
820 logmsg(LOG_ERR
, "advertise_event: Unknown event %d\n",
822 return (TIMER_INFINITY
);
825 if (pi
->pi_adv_time_left
!= 0)
826 return (pi
->pi_adv_time_left
);
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
);
833 advertise(&v6allnodes
, pi
, _B_FALSE
);
835 pi
->pi_adv_time_since_sent
= 0;
837 switch (pi
->pi_adv_state
) {
840 * The solicited advertisement has been sent.
841 * Revert to periodic advertisements.
843 pi
->pi_adv_state
= REG_ADV
;
846 pi
->pi_adv_time_left
=
847 GET_RANDOM(1000 * pi
->pi_MinRtrAdvInterval
,
848 1000 * pi
->pi_MaxRtrAdvInterval
);
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
;
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
;
867 if (--pi
->pi_adv_count
> 0) {
868 pi
->pi_adv_time_left
=
869 ND_MAX_INITIAL_RTR_ADVERT_INTERVAL
;
871 pi
->pi_adv_state
= NO_ADV
;
875 if (pi
->pi_adv_state
!= NO_ADV
)
876 return (pi
->pi_adv_time_left
);
878 return (TIMER_INFINITY
);
882 * Router solicitation state machine. Used for everything but timer
883 * events which use solicit_event directly.
886 check_to_solicit(struct phyint
*pi
, enum solicit_events event
)
889 enum solicit_states old_state
= pi
->pi_sol_state
;
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
);
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
);
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
);
912 boolean_t timerval
= _B_TRUE
;
915 * Need to get current timer settings so they can be restored
916 * after the fork(), as the it_value and it_interval values for
917 * the ITIMER_REAL timer are reset to 0 in the child process.
919 if (getitimer(ITIMER_REAL
, &it
) < 0) {
922 "daemonize_ndpd: failed to get itimerval\n");
927 if (daemon(0, 0) == -1) {
932 already_daemonized
= _B_TRUE
;
935 * Restore timer values, if we were able to save them; if not,
936 * check and set the right value by calling run_timeouts().
939 if (setitimer(ITIMER_REAL
, &it
, NULL
) < 0) {
940 logperror("daemonize_ndpd: setitimer");
949 * Check to see if the time is right to daemonize. The right time is when:
951 * 1. We haven't already daemonized.
952 * 2. We are not in debug mode.
953 * 3. All interfaces are marked IFF_NOXMIT.
954 * 4. All non-router interfaces have their prefixes set up and we're
955 * done sending router solicitations on those interfaces without
959 check_daemonize(void)
963 if (already_daemonized
|| debug
!= 0)
966 for (pi
= phyints
; pi
!= NULL
; pi
= pi
->pi_next
) {
967 if (!(pi
->pi_flags
& IFF_NOXMIT
))
972 * If we can't transmit on any of the interfaces there is no reason
973 * to hold up progress.
980 /* Check all interfaces. If any are still soliciting, just return. */
981 for (pi
= phyints
; pi
!= NULL
; pi
= pi
->pi_next
) {
982 if (pi
->pi_AdvSendAdvertisements
||
983 !(pi
->pi_kernel_state
& PI_PRESENT
))
986 if (pi
->pi_sol_state
== INIT_SOLICIT
)
994 * Router solicitation state machine.
995 * Return the number of milliseconds until next timeout (TIMER_INFINITY
997 * For the SOL_TIMER event the caller passes in the number of milliseconds
998 * since the last timer event in the 'elapsed' parameter.
1001 solicit_event(struct phyint
*pi
, enum solicit_events event
, uint_t elapsed
)
1003 if (debug
& D_STATE
) {
1004 logmsg(LOG_DEBUG
, "solicit_event(%s, %d, %d) state %d\n",
1005 pi
->pi_name
, (int)event
, elapsed
, (int)pi
->pi_sol_state
);
1008 if (pi
->pi_AdvSendAdvertisements
)
1009 return (TIMER_INFINITY
);
1010 if (pi
->pi_flags
& IFF_NORTEXCH
) {
1011 if (debug
& D_PKTOUT
) {
1012 logmsg(LOG_DEBUG
, "Suppress sending RS packet on %s "
1013 "(no route exchange on interface)\n",
1016 return (TIMER_INFINITY
);
1021 pi
->pi_sol_state
= NO_SOLICIT
;
1023 return (TIMER_INFINITY
);
1026 pi
->pi_sol_state
= DONE_SOLICIT
;
1028 return (TIMER_INFINITY
);
1030 case RESTART_INIT_SOLICIT
:
1032 * This event allows us to start solicitation over again
1033 * without losing the RA flags. We start solicitation over
1034 * when we are missing an interface prefix for a newly-
1035 * encountered DHCP interface.
1037 if (pi
->pi_sol_state
== INIT_SOLICIT
)
1038 return (pi
->pi_sol_time_left
);
1039 pi
->pi_sol_count
= ND_MAX_RTR_SOLICITATIONS
;
1040 pi
->pi_sol_time_left
=
1041 GET_RANDOM(0, ND_MAX_RTR_SOLICITATION_DELAY
);
1042 pi
->pi_sol_state
= INIT_SOLICIT
;
1045 case START_INIT_SOLICIT
:
1046 if (pi
->pi_sol_state
== INIT_SOLICIT
)
1047 return (pi
->pi_sol_time_left
);
1048 pi
->pi_ra_flags
= 0;
1049 pi
->pi_sol_count
= ND_MAX_RTR_SOLICITATIONS
;
1050 pi
->pi_sol_time_left
=
1051 GET_RANDOM(0, ND_MAX_RTR_SOLICITATION_DELAY
);
1052 pi
->pi_sol_state
= INIT_SOLICIT
;
1056 if (pi
->pi_sol_state
== NO_SOLICIT
)
1057 return (TIMER_INFINITY
);
1058 /* Decrease time left */
1059 if (pi
->pi_sol_time_left
>= elapsed
)
1060 pi
->pi_sol_time_left
-= elapsed
;
1062 pi
->pi_sol_time_left
= 0;
1065 logmsg(LOG_ERR
, "solicit_event: Unknown event %d\n",
1067 return (TIMER_INFINITY
);
1070 if (pi
->pi_sol_time_left
!= 0)
1071 return (pi
->pi_sol_time_left
);
1073 /* Send solicitation and calculate next time */
1074 switch (pi
->pi_sol_state
) {
1076 solicit(&v6allrouters
, pi
);
1077 if (--pi
->pi_sol_count
== 0) {
1078 if (debug
& D_STATE
) {
1079 logmsg(LOG_DEBUG
, "solicit_event: no routers "
1080 "found on %s; assuming default flags\n",
1083 if (pi
->pi_autoconf
&& pi
->pi_StatefulAddrConf
) {
1084 pi
->pi_ra_flags
|= ND_RA_FLAG_MANAGED
|
1088 pi
->pi_sol_state
= DONE_SOLICIT
;
1090 return (TIMER_INFINITY
);
1092 pi
->pi_sol_time_left
= ND_RTR_SOLICITATION_INTERVAL
;
1093 return (pi
->pi_sol_time_left
);
1096 return (TIMER_INFINITY
);
1098 return (pi
->pi_sol_time_left
);
1103 * Timer mechanism using relative time (in milliseconds) from the
1104 * previous timer event. Timers exceeding TIMER_INFINITY milliseconds
1105 * will fire after TIMER_INFINITY milliseconds.
1107 static uint_t timer_previous
; /* When last SIGALRM occurred */
1108 static uint_t timer_next
; /* Currently scheduled timeout */
1113 timer_previous
= getcurrenttime();
1114 timer_next
= TIMER_INFINITY
;
1119 * Make sure the next SIGALRM occurs delay milliseconds from the current
1120 * time if not earlier.
1121 * Handles getcurrenttime (32 bit integer holding milliseconds) wraparound
1122 * by treating differences greater than 0x80000000 as negative.
1125 timer_schedule(uint_t delay
)
1128 struct itimerval itimerval
;
1130 now
= getcurrenttime();
1131 if (debug
& D_TIMER
) {
1132 logmsg(LOG_DEBUG
, "timer_schedule(%u): now %u next %u\n",
1133 delay
, now
, timer_next
);
1135 /* Will this timer occur before the currently scheduled SIGALRM? */
1136 if (delay
>= timer_next
- now
) {
1137 if (debug
& D_TIMER
) {
1138 logmsg(LOG_DEBUG
, "timer_schedule(%u): no action - "
1140 delay
, timer_next
- now
);
1145 /* Minimum allowed delay */
1148 timer_next
= now
+ delay
;
1150 itimerval
.it_value
.tv_sec
= delay
/ 1000;
1151 itimerval
.it_value
.tv_usec
= (delay
% 1000) * 1000;
1152 itimerval
.it_interval
.tv_sec
= 0;
1153 itimerval
.it_interval
.tv_usec
= 0;
1154 if (debug
& D_TIMER
) {
1155 logmsg(LOG_DEBUG
, "timer_schedule(%u): sec %lu usec %lu\n",
1157 itimerval
.it_value
.tv_sec
, itimerval
.it_value
.tv_usec
);
1159 if (setitimer(ITIMER_REAL
, &itimerval
, NULL
) < 0) {
1160 logperror("timer_schedule: setitimer");
1166 * Conditional running of timer. If more than 'minimal_time' millseconds
1167 * since the timer routines were last run we run them.
1168 * Used when packets arrive.
1171 conditional_run_timeouts(uint_t minimal_time
)
1176 now
= getcurrenttime();
1177 elapsed
= now
- timer_previous
;
1178 if (elapsed
> minimal_time
) {
1179 if (debug
& D_TIMER
) {
1180 logmsg(LOG_DEBUG
, "conditional_run_timeouts: "
1181 "elapsed %d\n", elapsed
);
1189 * Determine when the next timer event will occur by asking all
1190 * the timer routines.
1191 * Should not be called from a timer routine but in some cases this is
1192 * done because the code doesn't know that e.g. it was called from
1193 * ifconfig_timer(). In this case the nested run_timeouts will just return but
1194 * the running run_timeouts will ensure to call all the timer functions by
1195 * looping once more.
1205 struct phyint
*next_pi
;
1207 struct prefix
*next_pr
;
1208 struct adv_prefix
*adv_pr
;
1209 struct adv_prefix
*next_adv_pr
;
1211 struct router
*next_dr
;
1212 static boolean_t timeout_running
;
1213 static boolean_t do_retry
;
1215 if (timeout_running
) {
1216 if (debug
& D_TIMER
)
1217 logmsg(LOG_DEBUG
, "run_timeouts: nested call\n");
1221 timeout_running
= _B_TRUE
;
1223 /* How much time since the last time we were called? */
1224 now
= getcurrenttime();
1225 elapsed
= now
- timer_previous
;
1226 timer_previous
= now
;
1228 if (debug
& D_TIMER
)
1229 logmsg(LOG_DEBUG
, "run_timeouts: elapsed %d\n", elapsed
);
1231 next
= TIMER_INFINITY
;
1232 for (pi
= phyints
; pi
!= NULL
; pi
= next_pi
) {
1233 next_pi
= pi
->pi_next
;
1234 nexti
= phyint_timer(pi
, elapsed
);
1235 if (nexti
!= TIMER_INFINITY
&& nexti
< next
)
1237 if (debug
& D_TIMER
) {
1238 logmsg(LOG_DEBUG
, "run_timeouts (pi %s): %d -> %u ms\n",
1239 pi
->pi_name
, nexti
, next
);
1241 for (pr
= pi
->pi_prefix_list
; pr
!= NULL
; pr
= next_pr
) {
1242 next_pr
= pr
->pr_next
;
1243 nexti
= prefix_timer(pr
, elapsed
);
1244 if (nexti
!= TIMER_INFINITY
&& nexti
< next
)
1246 if (debug
& D_TIMER
) {
1247 logmsg(LOG_DEBUG
, "run_timeouts (pr %s): "
1248 "%d -> %u ms\n", pr
->pr_name
, nexti
, next
);
1251 for (adv_pr
= pi
->pi_adv_prefix_list
; adv_pr
!= NULL
;
1252 adv_pr
= next_adv_pr
) {
1253 next_adv_pr
= adv_pr
->adv_pr_next
;
1254 nexti
= adv_prefix_timer(adv_pr
, elapsed
);
1255 if (nexti
!= TIMER_INFINITY
&& nexti
< next
)
1257 if (debug
& D_TIMER
) {
1258 logmsg(LOG_DEBUG
, "run_timeouts "
1259 "(adv pr on %s): %d -> %u ms\n",
1260 adv_pr
->adv_pr_physical
->pi_name
,
1264 for (dr
= pi
->pi_router_list
; dr
!= NULL
; dr
= next_dr
) {
1265 next_dr
= dr
->dr_next
;
1266 nexti
= router_timer(dr
, elapsed
);
1267 if (nexti
!= TIMER_INFINITY
&& nexti
< next
)
1269 if (debug
& D_TIMER
) {
1270 logmsg(LOG_DEBUG
, "run_timeouts (dr): "
1271 "%d -> %u ms\n", nexti
, next
);
1274 if (pi
->pi_TmpAddrsEnabled
) {
1275 nexti
= tmptoken_timer(pi
, elapsed
);
1276 if (nexti
!= TIMER_INFINITY
&& nexti
< next
)
1278 if (debug
& D_TIMER
) {
1279 logmsg(LOG_DEBUG
, "run_timeouts (tmp on %s): "
1280 "%d -> %u ms\n", pi
->pi_name
, nexti
, next
);
1285 * Make sure the timer functions are run at least once
1288 if (next
== TIMER_INFINITY
)
1289 next
= 3600 * 1000; /* 1 hour */
1291 if (debug
& D_TIMER
)
1292 logmsg(LOG_DEBUG
, "run_timeouts: %u ms\n", next
);
1293 timer_schedule(next
);
1295 if (debug
& D_TIMER
)
1296 logmsg(LOG_DEBUG
, "run_timeouts: retry\n");
1297 do_retry
= _B_FALSE
;
1300 timeout_running
= _B_FALSE
;
1303 static int eventpipe_read
= -1; /* Used for synchronous signal delivery */
1304 static int eventpipe_write
= -1;
1307 * Ensure that signals are processed synchronously with the rest of
1308 * the code by just writing a one character signal number on the pipe.
1309 * The poll loop will pick this up and process the signal event.
1312 sig_handler(int signo
)
1314 uchar_t buf
= (uchar_t
)signo
;
1316 if (eventpipe_write
== -1) {
1317 logmsg(LOG_ERR
, "sig_handler: no pipe\n");
1320 if (write(eventpipe_write
, &buf
, sizeof (buf
)) < 0)
1321 logperror("sig_handler: write");
1325 * Pick up a signal "byte" from the pipe and process it.
1332 struct phyint
*next_pi
;
1334 switch (read(fd
, &buf
, sizeof (buf
))) {
1336 logperror("in_signal: read");
1342 logmsg(LOG_ERR
, "in_signal: read eof\n");
1346 logmsg(LOG_ERR
, "in_signal: read > 1\n");
1350 if (debug
& D_TIMER
)
1351 logmsg(LOG_DEBUG
, "in_signal() got %d\n", buf
);
1355 if (debug
& D_TIMER
) {
1356 uint_t now
= getcurrenttime();
1358 logmsg(LOG_DEBUG
, "in_signal(SIGALRM) delta %u\n",
1361 timer_next
= TIMER_INFINITY
;
1365 /* Re-read config file by exec'ing ourselves */
1366 for (pi
= phyints
; pi
!= NULL
; pi
= next_pi
) {
1367 next_pi
= pi
->pi_next
;
1368 if (pi
->pi_AdvSendAdvertisements
)
1369 check_to_advertise(pi
, START_FINAL_ADV
);
1372 * Remove all the configured addresses.
1373 * Remove the addrobj names created with ipmgmtd.
1374 * Release the dhcpv6 addresses if any.
1375 * Cleanup the phyints.
1381 * Prevent fd leaks. Everything gets re-opened at start-up
1382 * time. 0, 1, and 2 are closed and re-opened as
1383 * /dev/null, so we'll leave those open.
1387 logmsg(LOG_ERR
, "SIGHUP: restart and reread config file\n");
1388 (void) execv(argv0
[0], argv0
);
1392 logmsg(LOG_DEBUG
, "Printing configuration:\n");
1398 for (pi
= phyints
; pi
!= NULL
; pi
= next_pi
) {
1399 next_pi
= pi
->pi_next
;
1400 if (pi
->pi_AdvSendAdvertisements
)
1401 check_to_advertise(pi
, START_FINAL_ADV
);
1405 (void) unlink(NDPD_SNMP_SOCKET
);
1410 * Special "signal" from loopback_ra_enqueue.
1411 * Handle any queued loopback router advertisements.
1413 loopback_ra_dequeue();
1416 logmsg(LOG_ERR
, "in_signal: unknown signal: %d\n", buf
);
1421 * Create pipe for signal delivery and set up signal handlers.
1424 setup_eventpipe(void)
1427 struct sigaction act
;
1429 if ((pipe(fds
)) < 0) {
1430 logperror("setup_eventpipe: pipe");
1433 eventpipe_read
= fds
[0];
1434 eventpipe_write
= fds
[1];
1435 if (poll_add(eventpipe_read
) == -1) {
1438 act
.sa_handler
= sig_handler
;
1439 act
.sa_flags
= SA_RESTART
;
1440 (void) sigaction(SIGALRM
, &act
, NULL
);
1442 (void) sigset(SIGHUP
, sig_handler
);
1443 (void) sigset(SIGUSR1
, sig_handler
);
1444 (void) sigset(SIGTERM
, sig_handler
);
1445 (void) sigset(SIGINT
, sig_handler
);
1446 (void) sigset(SIGQUIT
, sig_handler
);
1450 * Create a routing socket for receiving RTM_IFINFO messages and initialize
1451 * the routing socket message header and as much of the sockaddrs as possible.
1459 struct sockaddr_in6
*sin6
;
1461 s
= socket(PF_ROUTE
, SOCK_RAW
, AF_INET6
);
1463 logperror("socket(PF_ROUTE)");
1466 ret
= fcntl(s
, F_SETFL
, O_NDELAY
|O_NONBLOCK
);
1468 logperror("fcntl(O_NDELAY)");
1471 if (poll_add(s
) == -1) {
1476 * Allocate storage for the routing socket message.
1478 rt_msg
= (struct rt_msghdr
*)malloc(NDP_RTM_MSGLEN
);
1479 if (rt_msg
== NULL
) {
1480 logperror("malloc");
1485 * Initialize the routing socket message by zero-filling it and then
1486 * setting the fields where are constant through the lifetime of the
1489 bzero(rt_msg
, NDP_RTM_MSGLEN
);
1490 rt_msg
->rtm_msglen
= NDP_RTM_MSGLEN
;
1491 rt_msg
->rtm_version
= RTM_VERSION
;
1492 rt_msg
->rtm_addrs
= RTA_DST
| RTA_GATEWAY
| RTA_NETMASK
| RTA_IFP
;
1493 rt_msg
->rtm_pid
= getpid();
1494 if (rt_msg
->rtm_pid
< 0) {
1495 logperror("getpid");
1500 * The RTA_DST sockaddr does not change during the lifetime of the
1501 * process so it can be completely initialized at this time.
1503 cp
= (char *)rt_msg
+ sizeof (struct rt_msghdr
);
1504 sin6
= (struct sockaddr_in6
*)cp
;
1505 sin6
->sin6_family
= AF_INET6
;
1506 sin6
->sin6_addr
= in6addr_any
;
1509 * Initialize the constant portion of the RTA_GATEWAY sockaddr.
1511 cp
+= sizeof (struct sockaddr_in6
);
1512 rta_gateway
= (struct sockaddr_in6
*)cp
;
1513 rta_gateway
->sin6_family
= AF_INET6
;
1516 * The RTA_NETMASK sockaddr does not change during the lifetime of the
1517 * process so it can be completely initialized at this time.
1519 cp
+= sizeof (struct sockaddr_in6
);
1520 sin6
= (struct sockaddr_in6
*)cp
;
1521 sin6
->sin6_family
= AF_INET6
;
1522 sin6
->sin6_addr
= in6addr_any
;
1525 * Initialize the constant portion of the RTA_IFP sockaddr.
1527 cp
+= sizeof (struct sockaddr_in6
);
1528 rta_ifp
= (struct sockaddr_dl
*)cp
;
1529 rta_ifp
->sdl_family
= AF_LINK
;
1540 struct sockaddr_un laddr
;
1542 sock
= socket(AF_UNIX
, SOCK_DGRAM
, 0);
1544 logperror("setup_mibsock: socket(AF_UNIX)");
1548 bzero(&laddr
, sizeof (laddr
));
1549 laddr
.sun_family
= AF_UNIX
;
1551 (void) strncpy(laddr
.sun_path
, NDPD_SNMP_SOCKET
,
1552 sizeof (laddr
.sun_path
));
1553 len
= sizeof (struct sockaddr_un
);
1555 (void) unlink(NDPD_SNMP_SOCKET
);
1556 ret
= bind(sock
, (struct sockaddr
*)&laddr
, len
);
1558 logperror("setup_mibsock: bind\n");
1562 ret
= fcntl(sock
, F_SETFL
, O_NONBLOCK
);
1564 logperror("fcntl(O_NONBLOCK)");
1567 if (poll_add(sock
) == -1) {
1574 * Retrieve one routing socket message. If RTM_IFINFO indicates
1575 * new phyint do a full scan of the interfaces. If RTM_IFINFO
1576 * indicates an existing phyint, only scan that phyint and associated
1580 process_rtsock(int rtsock
)
1583 #define MSG_SIZE 2048/8
1584 int64_t msg
[MSG_SIZE
];
1585 struct rt_msghdr
*rtm
;
1586 struct if_msghdr
*ifm
;
1589 boolean_t need_initifs
= _B_FALSE
;
1590 boolean_t need_ifscan
= _B_FALSE
;
1591 int64_t ifscan_msg
[10][MSG_SIZE
];
1592 int ifscan_index
= 0;
1595 /* Empty the rtsock and coealesce all the work that we have */
1596 while (ifscan_index
< 10) {
1597 n
= read(rtsock
, msg
, sizeof (msg
));
1599 /* No more messages */
1602 rtm
= (struct rt_msghdr
*)msg
;
1603 if (rtm
->rtm_version
!= RTM_VERSION
) {
1605 "process_rtsock: version %d not understood\n",
1609 switch (rtm
->rtm_type
) {
1613 * Some logical interface has changed - have to scan
1614 * everything to determine what actually changed.
1616 if (debug
& D_IFSCAN
) {
1617 logmsg(LOG_DEBUG
, "process_rtsock: "
1618 "message %d\n", rtm
->rtm_type
);
1620 need_initifs
= _B_TRUE
;
1623 need_ifscan
= _B_TRUE
;
1624 (void) memcpy(ifscan_msg
[ifscan_index
], rtm
,
1630 /* Not interesting */
1635 * If we do full scan i.e initifs, we don't need to
1636 * scan a particular interface as we should have
1637 * done that as part of initifs.
1647 for (i
= 0; i
< ifscan_index
; i
++) {
1648 ifm
= (struct if_msghdr
*)ifscan_msg
[i
];
1649 if (debug
& D_IFSCAN
)
1650 logmsg(LOG_DEBUG
, "process_rtsock: index %d\n",
1653 pi
= phyint_lookup_on_index(ifm
->ifm_index
);
1656 * A new physical interface. Do a full scan of the
1657 * to catch any new logical interfaces.
1663 if (ifm
->ifm_flags
!= (uint_t
)pi
->pi_flags
) {
1664 if (debug
& D_IFSCAN
) {
1665 logmsg(LOG_DEBUG
, "process_rtsock: clr for "
1666 "%s old flags 0x%llx new flags 0x%x\n",
1667 pi
->pi_name
, pi
->pi_flags
, ifm
->ifm_flags
);
1673 * Mark the interfaces so that we can find phyints and prefixes
1674 * which have disappeared from the kernel.
1675 * if_process will set pr_in_use when it finds the
1676 * interface in the kernel.
1677 * Before re-examining the state of the interfaces,
1678 * PI_PRESENT should be cleared from pi_kernel_state.
1680 pi
->pi_kernel_state
&= ~PI_PRESENT
;
1681 for (pr
= pi
->pi_prefix_list
; pr
!= NULL
; pr
= pr
->pr_next
) {
1682 pr
->pr_in_use
= _B_FALSE
;
1686 ifsock
= socket(AF_INET6
, SOCK_DGRAM
, 0);
1688 logperror("process_rtsock: socket");
1692 if_process(ifsock
, pi
->pi_name
, _B_FALSE
);
1693 for (pr
= pi
->pi_prefix_list
; pr
!= NULL
; pr
= pr
->pr_next
) {
1694 if_process(ifsock
, pr
->pr_name
, _B_FALSE
);
1697 * If interface (still) exists in kernel, set
1698 * pi_state to indicate that.
1700 if (pi
->pi_kernel_state
& PI_PRESENT
) {
1701 pi
->pi_state
|= PI_PRESENT
;
1703 check_if_removed(pi
);
1710 process_mibsock(int mibsock
)
1714 struct sockaddr_un from
;
1715 ndpd_info_t ndpd_info
;
1719 fromlen
= (socklen_t
)sizeof (from
);
1720 len
= recvfrom(mibsock
, &command
, sizeof (int), 0,
1721 (struct sockaddr
*)&from
, &fromlen
);
1723 if (len
< sizeof (int) || command
!= NDPD_SNMP_INFO_REQ
) {
1724 logperror("process_mibsock: bad command \n");
1728 ndpd_info
.info_type
= NDPD_SNMP_INFO_RESPONSE
;
1729 ndpd_info
.info_version
= NDPD_SNMP_INFO_VER
;
1730 ndpd_info
.info_num_of_phyints
= num_of_phyints
;
1732 (void) sendto(mibsock
, &ndpd_info
, sizeof (ndpd_info_t
), 0,
1733 (struct sockaddr
*)&from
, fromlen
);
1735 for (pi
= phyints
; pi
!= NULL
; pi
= pi
->pi_next
) {
1738 struct prefix
*prefix_list
;
1739 struct router
*router_list
;
1740 ndpd_phyint_info_t phyint
;
1741 ndpd_prefix_info_t prefix
;
1742 ndpd_router_info_t router
;
1744 * get number of prefixes
1748 prefix_list
= pi
->pi_prefix_list
;
1749 while (prefix_list
!= NULL
) {
1751 prefix_list
= prefix_list
->pr_next
;
1755 * get number of routers
1757 router_list
= pi
->pi_router_list
;
1758 while (router_list
!= NULL
) {
1760 router_list
= router_list
->dr_next
;
1763 phyint
.phyint_info_type
= NDPD_PHYINT_INFO
;
1764 phyint
.phyint_info_version
= NDPD_PHYINT_INFO_VER
;
1765 phyint
.phyint_index
= pi
->pi_index
;
1766 bcopy(pi
->pi_config
,
1767 phyint
.phyint_config
, I_IFSIZE
);
1768 phyint
.phyint_num_of_prefixes
= prefixes
;
1769 phyint
.phyint_num_of_routers
= routers
;
1770 (void) sendto(mibsock
, &phyint
, sizeof (phyint
), 0,
1771 (struct sockaddr
*)&from
, fromlen
);
1774 * Copy prefix information
1777 prefix_list
= pi
->pi_prefix_list
;
1778 while (prefix_list
!= NULL
) {
1779 prefix
.prefix_info_type
= NDPD_PREFIX_INFO
;
1780 prefix
.prefix_info_version
= NDPD_PREFIX_INFO_VER
;
1781 prefix
.prefix_prefix
= prefix_list
->pr_prefix
;
1782 prefix
.prefix_len
= prefix_list
->pr_prefix_len
;
1783 prefix
.prefix_flags
= prefix_list
->pr_flags
;
1784 prefix
.prefix_phyint_index
= pi
->pi_index
;
1785 prefix
.prefix_ValidLifetime
=
1786 prefix_list
->pr_ValidLifetime
;
1787 prefix
.prefix_PreferredLifetime
=
1788 prefix_list
->pr_PreferredLifetime
;
1789 prefix
.prefix_OnLinkLifetime
=
1790 prefix_list
->pr_OnLinkLifetime
;
1791 prefix
.prefix_OnLinkFlag
=
1792 prefix_list
->pr_OnLinkFlag
;
1793 prefix
.prefix_AutonomousFlag
=
1794 prefix_list
->pr_AutonomousFlag
;
1795 (void) sendto(mibsock
, &prefix
, sizeof (prefix
), 0,
1796 (struct sockaddr
*)&from
, fromlen
);
1797 prefix_list
= prefix_list
->pr_next
;
1800 * Copy router information
1802 router_list
= pi
->pi_router_list
;
1803 while (router_list
!= NULL
) {
1804 router
.router_info_type
= NDPD_ROUTER_INFO
;
1805 router
.router_info_version
= NDPD_ROUTER_INFO_VER
;
1806 router
.router_address
= router_list
->dr_address
;
1807 router
.router_lifetime
= router_list
->dr_lifetime
;
1808 router
.router_phyint_index
= pi
->pi_index
;
1809 (void) sendto(mibsock
, &router
, sizeof (router
), 0,
1810 (struct sockaddr
*)&from
, fromlen
);
1811 router_list
= router_list
->dr_next
;
1817 * Look if the phyint or one of its prefixes have been removed from
1818 * the kernel and take appropriate action.
1819 * Uses pr_in_use and pi{,_kernel}_state.
1822 check_if_removed(struct phyint
*pi
)
1824 struct prefix
*pr
, *next_pr
;
1827 * Detect prefixes which are removed.
1828 * Static prefixes are just removed from our tables.
1829 * Non-static prefixes are recreated i.e. in.ndpd takes precedence
1830 * over manually removing prefixes via ifconfig.
1832 for (pr
= pi
->pi_prefix_list
; pr
!= NULL
; pr
= next_pr
) {
1833 next_pr
= pr
->pr_next
;
1834 if (!pr
->pr_in_use
) {
1835 /* Clear everything except PR_STATIC */
1836 pr
->pr_kernel_state
&= PR_STATIC
;
1837 if (pr
->pr_state
& PR_STATIC
)
1838 prefix_update_ipadm_addrobj(pr
, _B_FALSE
);
1839 pr
->pr_name
[0] = '\0';
1840 if (pr
->pr_state
& PR_STATIC
) {
1842 } else if (!(pi
->pi_kernel_state
& PI_PRESENT
)) {
1844 * Ensure that there are no future attempts to
1845 * run prefix_update_k since the phyint is gone.
1847 pr
->pr_state
= pr
->pr_kernel_state
;
1848 } else if (pr
->pr_state
!= pr
->pr_kernel_state
) {
1849 logmsg(LOG_INFO
, "Prefix manually removed "
1850 "on %s; recreating\n", pi
->pi_name
);
1851 prefix_update_k(pr
);
1857 * Detect phyints that have been removed from the kernel, and tear
1858 * down any prefixes we created that are associated with that phyint.
1859 * (NOTE: IPMP depends on in.ndpd tearing down these prefixes so an
1860 * administrator can easily place an IP interface with ADDRCONF'd
1861 * addresses into an IPMP group.)
1863 if (!(pi
->pi_kernel_state
& PI_PRESENT
) &&
1864 (pi
->pi_state
& PI_PRESENT
)) {
1865 logmsg(LOG_ERR
, "Interface %s has been removed from kernel. "
1866 "in.ndpd will no longer use it\n", pi
->pi_name
);
1868 for (pr
= pi
->pi_prefix_list
; pr
!= NULL
; pr
= next_pr
) {
1869 next_pr
= pr
->pr_next
;
1870 if (pr
->pr_state
& PR_AUTO
)
1871 prefix_update_ipadm_addrobj(pr
, _B_FALSE
);
1876 * Clear state so that should the phyint reappear we will
1877 * start with initial advertisements or solicitations.
1885 * Queuing mechanism for router advertisements that are sent by in.ndpd
1886 * and that also need to be processed by in.ndpd.
1887 * Uses "signal number" 255 to indicate to the main poll loop
1888 * that there is something to dequeue and send to incomining_ra().
1891 struct raq
*raq_next
;
1892 struct phyint
*raq_pi
;
1894 uchar_t
*raq_packet
;
1896 static struct raq
*raq_head
= NULL
;
1899 * Allocate a struct raq and memory for the packet.
1900 * Send signal 255 to have poll dequeue.
1903 loopback_ra_enqueue(struct phyint
*pi
, struct nd_router_advert
*ra
, int len
)
1911 if (debug
& D_PKTOUT
)
1912 logmsg(LOG_DEBUG
, "loopback_ra_enqueue for %s\n", pi
->pi_name
);
1914 raq
= calloc(sizeof (struct raq
), 1);
1916 logmsg(LOG_ERR
, "loopback_ra_enqueue: out of memory\n");
1919 raq
->raq_packet
= malloc(len
);
1920 if (raq
->raq_packet
== NULL
) {
1922 logmsg(LOG_ERR
, "loopback_ra_enqueue: out of memory\n");
1925 bcopy(ra
, raq
->raq_packet
, len
);
1926 raq
->raq_packetlen
= len
;
1931 while (*raqp
!= NULL
)
1932 raqp
= &((*raqp
)->raq_next
);
1935 /* Signal for poll loop */
1940 * Dequeue and process all queued advertisements.
1943 loopback_ra_dequeue(void)
1945 struct sockaddr_in6 from
= IN6ADDR_LOOPBACK_INIT
;
1948 if (debug
& D_PKTIN
)
1949 logmsg(LOG_DEBUG
, "loopback_ra_dequeue()\n");
1951 while ((raq
= raq_head
) != NULL
) {
1952 raq_head
= raq
->raq_next
;
1953 raq
->raq_next
= NULL
;
1955 if (debug
& D_PKTIN
) {
1956 logmsg(LOG_DEBUG
, "loopback_ra_dequeue for %s\n",
1957 raq
->raq_pi
->pi_name
);
1960 incoming_ra(raq
->raq_pi
,
1961 (struct nd_router_advert
*)raq
->raq_packet
,
1962 raq
->raq_packetlen
, &from
, _B_TRUE
);
1963 free(raq
->raq_packet
);
1972 (void) fprintf(stderr
,
1973 "usage: %s [ -adt ] [-f <config file>]\n", cmd
);
1977 main(int argc
, char *argv
[])
1982 char *config_file
= PATH_NDPD_CONF
;
1983 boolean_t file_required
= _B_FALSE
;
1986 srandom(gethostid());
1989 while ((c
= getopt(argc
, argv
, "adD:ntIf:")) != EOF
) {
1993 * The StatelessAddrConf variable in ndpd.conf, if
1994 * present, will override this setting.
1996 ifdefaults
[I_StatelessAddrConf
].cf_value
= 0;
2002 i
= strtol((char *)optarg
, NULL
, 0);
2004 (void) fprintf(stderr
, "Bad debug flags: %s\n",
2017 debug
|= D_PKTIN
| D_PKTOUT
| D_PKTBAD
;
2020 config_file
= (char *)optarg
;
2021 file_required
= _B_TRUE
;
2029 if (parse_config(config_file
, file_required
) == -1)
2038 cmdsock
= ndpd_setup_cmd_listener();
2040 rtsock
= setup_rtsock();
2041 mibsock
= setup_mibsock();
2048 if (poll(pollfds
, pollfd_num
, -1) < 0) {
2051 logperror("main: poll");
2054 for (i
= 0; i
< pollfd_num
; i
++) {
2055 if (!(pollfds
[i
].revents
& POLLIN
))
2057 if (pollfds
[i
].fd
== eventpipe_read
) {
2058 in_signal(eventpipe_read
);
2061 if (pollfds
[i
].fd
== rtsock
) {
2062 process_rtsock(rtsock
);
2065 if (pollfds
[i
].fd
== mibsock
) {
2066 process_mibsock(mibsock
);
2069 if (pollfds
[i
].fd
== cmdsock
) {
2070 ndpd_cmd_handler(cmdsock
);
2074 * Run timer routine to advance clock if more than
2075 * half a second since the clock was advanced.
2076 * This limits CPU usage under severe packet
2077 * arrival rates but it creates a slight inaccuracy
2078 * in the timer mechanism.
2080 conditional_run_timeouts(500U);
2081 for (pi
= phyints
; pi
!= NULL
; pi
= pi
->pi_next
) {
2082 if (pollfds
[i
].fd
== pi
->pi_sock
) {
2097 static boolean_t logging
= _B_FALSE
;
2103 openlog("in.ndpd", LOG_PID
| LOG_CONS
, LOG_DAEMON
);
2106 /* Print the date/time without a trailing carridge return */
2108 fprintdate(FILE *file
)
2115 (void) localtime_r(&now
, &tms
);
2116 (void) strftime(buf
, sizeof (buf
), "%h %d %X", &tms
);
2117 (void) fprintf(file
, "%s ", buf
);
2122 logmsg(int level
, const char *fmt
, ...)
2128 vsyslog(level
, fmt
, ap
);
2131 (void) vfprintf(stderr
, fmt
, ap
);
2137 logperror(const char *str
)
2140 syslog(LOG_ERR
, "%s: %m\n", str
);
2143 (void) fprintf(stderr
, "%s: %s\n", str
, strerror(errno
));
2148 logperror_pi(const struct phyint
*pi
, const char *str
)
2151 syslog(LOG_ERR
, "%s (interface %s): %m\n",
2155 (void) fprintf(stderr
, "%s (interface %s): %s\n",
2156 str
, pi
->pi_name
, strerror(errno
));
2161 logperror_pr(const struct prefix
*pr
, const char *str
)
2164 syslog(LOG_ERR
, "%s (prefix %s if %s): %m\n",
2165 str
, pr
->pr_name
, pr
->pr_physical
->pi_name
);
2168 (void) fprintf(stderr
, "%s (prefix %s if %s): %s\n",
2169 str
, pr
->pr_name
, pr
->pr_physical
->pi_name
,
2175 ndpd_setup_cmd_listener(void)
2179 struct sockaddr_un servaddr
;
2181 sock
= socket(AF_UNIX
, SOCK_STREAM
, 0);
2183 logperror("socket");
2187 bzero(&servaddr
, sizeof (servaddr
));
2188 servaddr
.sun_family
= AF_UNIX
;
2189 (void) strlcpy(servaddr
.sun_path
, IPADM_UDS_PATH
,
2190 sizeof (servaddr
.sun_path
));
2191 (void) unlink(servaddr
.sun_path
);
2192 ret
= bind(sock
, (struct sockaddr
*)&servaddr
, sizeof (servaddr
));
2197 if (listen(sock
, 30) < 0) {
2198 logperror("listen");
2201 if (poll_add(sock
) == -1) {
2202 logmsg(LOG_ERR
, "command socket could not be added to the "
2211 * Commands received over the command socket come here
2214 ndpd_cmd_handler(int sock
)
2217 struct sockaddr_storage peer
;
2219 ipadm_ndpd_msg_t ndpd_msg
;
2222 peerlen
= sizeof (peer
);
2223 newfd
= accept(sock
, (struct sockaddr
*)&peer
, &peerlen
);
2225 logperror("accept");
2229 retval
= ipadm_ndpd_read(newfd
, &ndpd_msg
, sizeof (ndpd_msg
));
2231 logperror("Could not read ndpd command");
2233 retval
= ndpd_process_cmd(newfd
, &ndpd_msg
);
2235 logmsg(LOG_ERR
, "ndpd command on interface %s failed with "
2236 "error %s\n", ndpd_msg
.inm_ifname
, strerror(retval
));
2238 (void) close(newfd
);
2242 * Process the commands received from the cmd listener socket.
2245 ndpd_process_cmd(int newfd
, ipadm_ndpd_msg_t
*msg
)
2249 if (!ipadm_check_auth()) {
2250 logmsg(LOG_ERR
, "User not authorized to send the command\n");
2251 (void) ndpd_send_error(newfd
, EPERM
);
2254 switch (msg
->inm_cmd
) {
2255 case IPADM_DISABLE_AUTOCONF
:
2256 err
= ndpd_set_autoconf(msg
->inm_ifname
, _B_FALSE
);
2259 case IPADM_ENABLE_AUTOCONF
:
2260 err
= ndpd_set_autoconf(msg
->inm_ifname
, _B_TRUE
);
2263 case IPADM_CREATE_ADDRS
:
2264 err
= ndpd_create_addrs(msg
->inm_ifname
, msg
->inm_intfid
,
2265 msg
->inm_intfidlen
, msg
->inm_stateless
,
2266 msg
->inm_stateful
, msg
->inm_aobjname
);
2269 case IPADM_DELETE_ADDRS
:
2270 err
= ndpd_delete_addrs(msg
->inm_ifname
);
2278 (void) ndpd_send_error(newfd
, err
);
2284 ndpd_send_error(int fd
, int error
)
2286 return (ipadm_ndpd_write(fd
, &error
, sizeof (error
)));
2290 * Disables/Enables autoconfiguration of addresses on the
2291 * given physical interface.
2292 * This is provided to support the legacy method of configuring IPv6
2293 * addresses. i.e. `ifconfig bge0 inet6 plumb` will plumb the interface
2294 * and start stateless and stateful autoconfiguration. If this function is
2295 * not called with enable=_B_FALSE, no autoconfiguration will be done until
2296 * ndpd_create_addrs() is called with an Interface ID.
2299 ndpd_set_autoconf(const char *ifname
, boolean_t enable
)
2303 pi
= phyint_lookup((char *)ifname
);
2306 * If the physical interface was plumbed but no
2307 * addresses were configured yet, phyint will not exist.
2309 pi
= phyint_create((char *)ifname
);
2311 logmsg(LOG_ERR
, "could not create phyint for "
2312 "interface %s", ifname
);
2316 pi
->pi_autoconf
= enable
;
2318 if (debug
& D_PHYINT
) {
2319 logmsg(LOG_DEBUG
, "ndpd_set_autoconf: %s autoconf for "
2320 "interface %s\n", (enable
? "enabled" : "disabled"),
2327 * Create auto-configured addresses on the given interface using
2328 * the given token as the interface id during the next Router Advertisement.
2329 * Currently, only one token per interface is supported.
2332 ndpd_create_addrs(const char *ifname
, struct sockaddr_in6 intfid
, int intfidlen
,
2333 boolean_t stateless
, boolean_t stateful
, char *addrobj
)
2337 struct sockaddr_in6
*sin6
;
2340 pi
= phyint_lookup((char *)ifname
);
2343 * If the physical interface was plumbed but no
2344 * addresses were configured yet, phyint will not exist.
2346 pi
= phyint_create((char *)ifname
);
2348 if (debug
& D_PHYINT
)
2349 logmsg(LOG_ERR
, "could not create phyint "
2350 "for interface %s", ifname
);
2353 } else if (pi
->pi_autoconf
) {
2354 logmsg(LOG_ERR
, "autoconfiguration already in progress\n");
2357 check_autoconf_var_consistency(pi
, stateless
, stateful
);
2359 if (intfidlen
== 0) {
2360 pi
->pi_default_token
= _B_TRUE
;
2362 ifsock
= socket(AF_INET6
, SOCK_DGRAM
, 0);
2365 logperror("ndpd_create_addrs: socket");
2369 (void) strncpy(lifr
.lifr_name
, ifname
, sizeof (lifr
.lifr_name
));
2370 sin6
= (struct sockaddr_in6
*)&lifr
.lifr_addr
;
2371 if (ioctl(ifsock
, SIOCGLIFTOKEN
, (char *)&lifr
) < 0) {
2373 logperror("SIOCGLIFTOKEN");
2376 pi
->pi_token
= sin6
->sin6_addr
;
2377 pi
->pi_token_length
= lifr
.lifr_addrlen
;
2379 pi
->pi_default_token
= _B_FALSE
;
2380 pi
->pi_token
= intfid
.sin6_addr
;
2381 pi
->pi_token_length
= intfidlen
;
2383 pi
->pi_stateless
= stateless
;
2384 pi
->pi_stateful
= stateful
;
2385 (void) strlcpy(pi
->pi_ipadm_aobjname
, addrobj
,
2386 sizeof (pi
->pi_ipadm_aobjname
));
2388 /* We can allow autoconfiguration now. */
2389 pi
->pi_autoconf
= _B_TRUE
;
2391 /* Restart the solicitations. */
2392 if (pi
->pi_sol_state
== DONE_SOLICIT
)
2393 pi
->pi_sol_state
= NO_SOLICIT
;
2394 if (pi
->pi_sol_state
== NO_SOLICIT
)
2395 check_to_solicit(pi
, START_INIT_SOLICIT
);
2396 if (debug
& D_PHYINT
)
2397 logmsg(LOG_DEBUG
, "ndpd_create_addrs: "
2398 "added token to interface %s\n", pi
->pi_name
);
2403 * This function deletes all addresses on the given interface
2404 * with the given Interface ID.
2407 ndpd_delete_addrs(const char *ifname
)
2410 struct prefix
*pr
, *next_pr
;
2414 pi
= phyint_lookup((char *)ifname
);
2416 logmsg(LOG_ERR
, "no phyint found for %s", ifname
);
2419 if (IN6_IS_ADDR_UNSPECIFIED(&pi
->pi_token
)) {
2420 logmsg(LOG_ERR
, "token does not exist for %s", ifname
);
2425 ifsock
= socket(AF_INET6
, SOCK_DGRAM
, 0);
2428 logperror("ndpd_create_addrs: socket");
2432 /* Remove the prefixes for this phyint if they exist */
2433 for (pr
= pi
->pi_prefix_list
; pr
!= NULL
; pr
= next_pr
) {
2434 next_pr
= pr
->pr_next
;
2435 if (pr
->pr_name
[0] == '\0') {
2440 * Delete all the prefixes for the auto-configured
2441 * addresses as well as the DHCPv6 addresses.
2443 (void) strncpy(lifr
.lifr_name
, pr
->pr_name
,
2444 sizeof (lifr
.lifr_name
));
2445 if (ioctl(ifsock
, SIOCGLIFFLAGS
, (char *)&lifr
) < 0) {
2447 logperror("SIOCGLIFFLAGS");
2450 if ((lifr
.lifr_flags
& IFF_ADDRCONF
) ||
2451 (lifr
.lifr_flags
& IFF_DHCPRUNNING
)) {
2452 prefix_update_ipadm_addrobj(pr
, _B_FALSE
);
2458 * If we had started dhcpagent, we need to release the leases
2459 * if any are required.
2461 if (pi
->pi_stateful
) {
2462 (void) strncpy(lifr
.lifr_name
, pi
->pi_name
,
2463 sizeof (lifr
.lifr_name
));
2464 if (ioctl(ifsock
, SIOCGLIFFLAGS
, (char *)&lifr
) < 0) {
2466 logperror("SIOCGLIFFLAGS");
2469 if (lifr
.lifr_flags
& IFF_DHCPRUNNING
)
2474 * Reset the Interface ID on this phyint and stop autoconfigurations
2475 * until a new interface ID is provided.
2477 pi
->pi_token
= in6addr_any
;
2478 pi
->pi_token_length
= 0;
2479 pi
->pi_autoconf
= _B_FALSE
;
2480 pi
->pi_ipadm_aobjname
[0] = '\0';
2482 /* Reset the stateless and stateful settings to default. */
2483 pi
->pi_stateless
= pi
->pi_StatelessAddrConf
;
2484 pi
->pi_stateful
= pi
->pi_StatefulAddrConf
;
2486 if (debug
& D_PHYINT
) {
2487 logmsg(LOG_DEBUG
, "ndpd_delete_addrs: "
2488 "removed token from interface %s\n", pi
->pi_name
);
2494 check_autoconf_var_consistency(struct phyint
*pi
, boolean_t stateless
,
2498 * If StatelessAddrConf and StatelessAddrConf are set in
2499 * /etc/inet/ndpd.conf, check if the new values override those
2500 * settings. If so, log a warning.
2502 if ((pi
->pi_StatelessAddrConf
!=
2503 ifdefaults
[I_StatelessAddrConf
].cf_value
&&
2504 stateless
!= pi
->pi_StatelessAddrConf
) ||
2505 (pi
->pi_StatefulAddrConf
!=
2506 ifdefaults
[I_StatefulAddrConf
].cf_value
&&
2507 stateful
!= pi
->pi_StatefulAddrConf
)) {
2508 logmsg(LOG_ERR
, "check_autoconf_var_consistency: "
2509 "Overriding the StatelessAddrConf or StatefulAddrConf "
2510 "settings in ndpd.conf with the new values for "
2511 "interface %s\n", pi
->pi_name
);
2516 * If ipadm was used to start autoconfiguration and in.ndpd was restarted
2517 * for some reason, in.ndpd has to resume autoconfiguration when it comes up.
2518 * In this function, it scans the ipadm_addr_info() output to find a link-local
2519 * on this interface with address type "addrconf" and extracts the interface id.
2520 * It also stores the addrobj name to be used later when new addresses are
2521 * created for the prefixes advertised by the router.
2522 * If autoconfiguration was never started on this interface before in.ndpd
2523 * was killed, then in.ndpd should refrain from configuring prefixes, even if
2524 * there is a valid link-local on this interface, created by ipadm (identified
2525 * if there is a valid addrobj name).
2528 phyint_check_ipadm_intfid(struct phyint
*pi
)
2530 ipadm_status_t status
;
2531 ipadm_addr_info_t
*addrinfo
;
2532 struct ifaddrs
*ifap
;
2533 ipadm_addr_info_t
*ainfop
;
2534 struct sockaddr_in6
*sin6
;
2537 if (ipadm_open(&iph
, 0) != IPADM_SUCCESS
) {
2538 logmsg(LOG_ERR
, "could not open handle to libipadm\n");
2542 status
= ipadm_addr_info(iph
, pi
->pi_name
, &addrinfo
,
2543 IPADM_OPT_ZEROADDR
, LIFC_NOXMIT
|LIFC_TEMPORARY
);
2544 if (status
!= IPADM_SUCCESS
) {
2548 pi
->pi_autoconf
= _B_TRUE
;
2549 for (ainfop
= addrinfo
; ainfop
!= NULL
; ainfop
= IA_NEXT(ainfop
)) {
2550 ifap
= &ainfop
->ia_ifa
;
2551 if (ifap
->ifa_addr
->sa_family
!= AF_INET6
||
2552 ainfop
->ia_state
== IFA_DISABLED
)
2554 sin6
= (struct sockaddr_in6
*)ifap
->ifa_addr
;
2555 if (IN6_IS_ADDR_LINKLOCAL(&sin6
->sin6_addr
)) {
2556 if (ainfop
->ia_atype
== IPADM_ADDR_IPV6_ADDRCONF
) {
2557 pi
->pi_token
= sin6
->sin6_addr
;
2558 pi
->pi_token
._S6_un
._S6_u32
[0] = 0;
2559 pi
->pi_token
._S6_un
._S6_u32
[1] = 0;
2560 pi
->pi_autoconf
= _B_TRUE
;
2561 (void) strlcpy(pi
->pi_ipadm_aobjname
,
2562 ainfop
->ia_aobjname
,
2563 sizeof (pi
->pi_ipadm_aobjname
));
2567 * If IFF_NOLINKLOCAL is set, then the link-local
2568 * was created using ipadm. Do not autoconfigure until
2569 * ipadm is explicitly used for autoconfiguration.
2571 if (ifap
->ifa_flags
& IFF_NOLINKLOCAL
)
2572 pi
->pi_autoconf
= _B_FALSE
;
2573 } else if (IN6_IS_ADDR_UNSPECIFIED(&sin6
->sin6_addr
) &&
2574 strrchr(ifap
->ifa_name
, ':') == NULL
) {
2575 /* The interface was created using ipadm. */
2576 pi
->pi_autoconf
= _B_FALSE
;
2579 ipadm_free_addr_info(addrinfo
);
2580 if (!pi
->pi_autoconf
) {
2581 pi
->pi_token
= in6addr_any
;
2582 pi
->pi_token_length
= 0;