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