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