- /*
- * in6_update_ifa() does not use ifra_name, but we accurately set it
- * for safety.
- */
- strncpy(ifra.ifra_name, if_name(ifp), sizeof(ifra.ifra_name));
-
- if (((ifp->if_type == IFT_PPP) || ((ifp->if_eflags & IFEF_NOAUTOIPV6LL) != 0)) &&
- ifra_passed != NULL) /* PPP provided both addresses for us */
- bcopy(&ifra_passed->ifra_addr, &(ifra.ifra_addr), sizeof(struct sockaddr_in6));
- else {
- ifra.ifra_addr.sin6_family = AF_INET6;
- ifra.ifra_addr.sin6_len = sizeof(struct sockaddr_in6);
- ifra.ifra_addr.sin6_addr.s6_addr16[0] = htons(0xfe80);
-#if SCOPEDROUTING
- ifra.ifra_addr.sin6_addr.s6_addr16[1] = 0
-#else
- ifra.ifra_addr.sin6_addr.s6_addr16[1] = htons(ifp->if_index); /* XXX */
-#endif
- ifra.ifra_addr.sin6_addr.s6_addr32[1] = 0;
- if ((ifp->if_flags & IFF_LOOPBACK) != 0) {
- ifra.ifra_addr.sin6_addr.s6_addr32[2] = 0;
- ifra.ifra_addr.sin6_addr.s6_addr32[3] = htonl(1);
- } else {
- if (get_ifid(ifp, altifp, &ifra.ifra_addr.sin6_addr) != 0) {
- nd6log((LOG_ERR,
- " %s: no ifid available\n", if_name(ifp)));
- return -1;
- }
- }
-#if SCOPEDROUTING
- ifra.ifra_addr.sin6_scope_id =
- in6_addr2scopeid(ifp, &ifra.ifra_addr.sin6_addr);
-#endif
- }
- ifra.ifra_prefixmask.sin6_len = sizeof(struct sockaddr_in6);
- ifra.ifra_prefixmask.sin6_family = AF_INET6;
- ifra.ifra_prefixmask.sin6_addr = in6mask64;
-#if SCOPEDROUTING
- /* take into accound the sin6_scope_id field for routing */
- ifra.ifra_prefixmask.sin6_scope_id = 0xffffffff;
-#endif
- /* link-local addresses should NEVER expire. */
- ifra.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;
- ifra.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
-
- /*
- * Do not let in6_update_ifa() do DAD, since we need a random delay
- * before sending an NS at the first time the interface becomes up.
- * Instead, in6_if_up() will start DAD with a proper random delay.
- */
- ifra.ifra_flags |= IN6_IFF_NODAD;
-
- /*
- * Now call in6_update_ifa() to do a bunch of procedures to configure
- * a link-local address. We can set NULL to the 3rd argument, because
- * we know there's no other link-local address on the interface
- * and therefore we are adding one (instead of updating one).
- */
- if ((error = in6_update_ifa(ifp, &ifra, NULL, M_WAITOK)) != 0) {