]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/netinet6/in6_ifattach.c
xnu-1228.tar.gz
[apple/xnu.git] / bsd / netinet6 / in6_ifattach.c
index 8fe4ea5eb5a73b1d2d819d68bf080626eaddb57a..b711892abb3f4d9e7815726d2d5230f76c2f60ef 100644 (file)
@@ -1,3 +1,30 @@
+/*
+ * Copyright (c) 2003-2007 Apple Inc. All rights reserved.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ * 
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ */
 /*     $FreeBSD: src/sys/netinet6/in6_ifattach.c,v 1.8 2002/04/19 04:46:22 suz Exp $   */
 /*     $KAME: in6_ifattach.c,v 1.118 2001/05/24 07:44:00 itojun Exp $  */
 
 #include <sys/sockio.h>
 #include <sys/kernel.h>
 #include <sys/syslog.h>
-#include <sys/md5.h>
+#include <libkern/crypto/md5.h>
+#include <libkern/OSAtomic.h>
+#include <kern/lock.h>
 
 #include <net/if.h>
 #include <net/if_dl.h>
 #include <net/if_types.h>
 #include <net/route.h>
+#include <net/kpi_protocol.h>
 
 #include <netinet/in.h>
 #include <netinet/in_var.h>
@@ -66,6 +96,7 @@ struct icmp6_ifstat **icmp6_ifstat = NULL;
 size_t in6_ifstatmax = 0;
 size_t icmp6_ifstatmax = 0;
 unsigned long in6_maxmtu = 0;
+extern lck_mtx_t *nd6_mutex;
 
 #if IP6_AUTO_LINKLOCAL
 int ip6_auto_linklocal = IP6_AUTO_LINKLOCAL;
@@ -73,16 +104,17 @@ int ip6_auto_linklocal = IP6_AUTO_LINKLOCAL;
 int ip6_auto_linklocal = 1;    /* enable by default */
 #endif
 
+int loopattach6_done = 0;
 
 extern struct inpcbinfo udbinfo;
 extern struct inpcbinfo ripcbinfo;
 
-static int get_rand_ifid __P((struct ifnet *, struct in6_addr *));
-static int generate_tmp_ifid __P((u_int8_t *, const u_int8_t *, u_int8_t *));
-static int get_hw_ifid __P((struct ifnet *, struct in6_addr *));
-static int get_ifid __P((struct ifnet *, struct ifnet *, struct in6_addr *));
-static int in6_ifattach_linklocal __P((struct ifnet *, struct ifnet *, struct in6_aliasreq *));
-static int in6_ifattach_loopback __P((struct ifnet *));
+static int get_rand_ifid(struct ifnet *, struct in6_addr *);
+static int generate_tmp_ifid(u_int8_t *, const u_int8_t *, u_int8_t *);
+static int get_hw_ifid(struct ifnet *, struct in6_addr *);
+static int get_ifid(struct ifnet *, struct ifnet *, struct in6_addr *);
+static int in6_ifattach_linklocal(struct ifnet *, struct ifnet *, struct in6_aliasreq *);
+static int in6_ifattach_loopback(struct ifnet *);
 
 #define EUI64_GBIT     0x01
 #define EUI64_UBIT     0x02
@@ -103,24 +135,24 @@ static int in6_ifattach_loopback __P((struct ifnet *));
  * We currently use MD5(hostname) for it.
  */
 static int
-get_rand_ifid(ifp, in6)
-       struct ifnet *ifp;
-       struct in6_addr *in6;   /* upper 64bits are preserved */
+get_rand_ifid(
+       __unused struct ifnet *ifp,
+       struct in6_addr *in6)   /* upper 64bits are preserved */
 {
        MD5_CTX ctxt;
        u_int8_t digest[16];
-       int hostnamelen = strlen(hostname);
+       int len = strlen(hostname);
 
 #if 0
        /* we need at least several letters as seed for ifid */
-       if (hostnamelen < 3)
+       if (len < 3)
                return -1;
 #endif
 
        /* generate 8 bytes of pseudo-random value. */
        bzero(&ctxt, sizeof(ctxt));
        MD5Init(&ctxt);
-       MD5Update(&ctxt, hostname, hostnamelen);
+       MD5Update(&ctxt, hostname, len);
        MD5Final(digest, &ctxt);
 
        /* assumes sizeof(digest) > sizeof(ifid) */
@@ -137,9 +169,10 @@ get_rand_ifid(ifp, in6)
 }
 
 static int
-generate_tmp_ifid(seed0, seed1, ret)
-       u_int8_t *seed0, *ret;
-       const u_int8_t *seed1;
+generate_tmp_ifid(
+       u_int8_t *seed0,
+       const u_int8_t *seed1,
+       u_int8_t *ret)
 {
        MD5_CTX ctxt;
        u_int8_t seed[16], digest[16], nullbuf[8];
@@ -226,9 +259,9 @@ generate_tmp_ifid(seed0, seed1, ret)
  * XXX assumes single sockaddr_dl (AF_LINK address) per an interface
  */
 static int
-get_hw_ifid(ifp, in6)
-       struct ifnet *ifp;
-       struct in6_addr *in6;   /* upper 64bits are preserved */
+get_hw_ifid(
+       struct ifnet *ifp,
+       struct in6_addr *in6)   /* upper 64bits are preserved */
 {
        struct ifaddr *ifa;
        struct sockaddr_dl *sdl;
@@ -238,6 +271,8 @@ get_hw_ifid(ifp, in6)
        static u_int8_t allone[8] =
                { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 
+       /* Why doesn't this code use ifnet_addrs? */
+       ifnet_lock_shared(ifp);
        for (ifa = ifp->if_addrlist.tqh_first;
             ifa;
             ifa = ifa->ifa_list.tqe_next)
@@ -252,11 +287,13 @@ get_hw_ifid(ifp, in6)
 
                goto found;
        }
+       ifnet_lock_done(ifp);
 
        return -1;
 
 found:
-       addr = LLADDR(sdl);
+       ifnet_lock_done(ifp);
+       addr = (u_int8_t *) LLADDR(sdl);
        addrlen = sdl->sdl_alen;
 
        /* get EUI64 */
@@ -265,6 +302,8 @@ found:
        case IFT_FDDI:
        case IFT_ATM:
        case IFT_IEEE1394:
+       case IFT_L2VLAN:
+       case IFT_IEEE8023ADLAG:
 #if IFT_IEEE80211
        case IFT_IEEE80211:
 #endif
@@ -359,10 +398,10 @@ found:
  * sources.
  */
 static int
-get_ifid(ifp0, altifp, in6)
-       struct ifnet *ifp0;
-       struct ifnet *altifp;   /* secondary EUI64 source */
-       struct in6_addr *in6;
+get_ifid(
+       struct ifnet *ifp0,
+       struct ifnet *altifp,   /* secondary EUI64 source */
+       struct in6_addr *in6)
 {
        struct ifnet *ifp;
 
@@ -381,8 +420,8 @@ get_ifid(ifp0, altifp, in6)
        }
 
        /* next, try to get it from some other hardware interface */
-       for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_list.tqe_next)
-       {
+       ifnet_head_lock_shared();
+       TAILQ_FOREACH(ifp, &ifnet_head, if_list) {
                if (ifp == ifp0)
                        continue;
                if (get_hw_ifid(ifp, in6) != 0)
@@ -396,9 +435,11 @@ get_ifid(ifp0, altifp, in6)
                        nd6log((LOG_DEBUG,
                            "%s: borrow interface identifier from %s\n",
                            if_name(ifp0), if_name(ifp)));
+                       ifnet_head_done();
                        goto success;
                }
        }
+       ifnet_head_done();
 
        /* last resort: get from random number source */
        if (get_rand_ifid(ifp, in6) == 0) {
@@ -423,22 +464,22 @@ success:
 }
 
 static int
-in6_ifattach_linklocal(ifp, altifp, ifra_passed)
-       struct ifnet *ifp;
-       struct ifnet *altifp;   /* secondary EUI64 source */
-       struct in6_aliasreq *ifra_passed;
+in6_ifattach_linklocal(
+       struct ifnet *ifp,
+       struct ifnet *altifp,   /* secondary EUI64 source */
+       struct in6_aliasreq *ifra_passed)
 {
        struct in6_ifaddr *ia;
        struct in6_aliasreq ifra;
-       struct nd_prefix pr0;
-       int i, dl_tag, error;
+       struct nd_prefix pr0, *pr;
+       int i, error;
 
        /*
         * configure link-local address.
         */
        bzero(&ifra, sizeof(ifra));
 
-       dlil_plumb_protocol(PF_INET6, ifp, &dl_tag);
+       proto_plumb(PF_INET6, ifp);
 
        /*
         * in6_update_ifa() does not use ifra_name, but we accurately set it
@@ -562,18 +603,23 @@ in6_ifattach_linklocal(ifp, altifp, ifra_passed)
         * address, and then reconfigure another one, the prefix is still
         * valid with referring to the old link-local address.
         */
-       if (nd6_prefix_lookup(&pr0) == NULL) {
-               if ((error = nd6_prelist_add(&pr0, NULL, NULL)) != 0)
+       if ((pr = nd6_prefix_lookup(&pr0)) == NULL) {
+               if ((error = nd6_prelist_add(&pr0, NULL, &pr)) != 0)
                        return(error);
        }
 
        in6_post_msg(ifp, KEV_INET6_NEW_LL_ADDR, ia);
+
+       /* Drop use count held above during lookup/add */
+       if (pr != NULL)
+               ndpr_rele(pr, FALSE);
+
        return 0;
 }
 
 static int
-in6_ifattach_loopback(ifp)
-       struct ifnet *ifp;      /* must be IFT_LOOP */
+in6_ifattach_loopback(
+       struct ifnet *ifp)      /* must be IFT_LOOP */
 {
        struct in6_aliasreq ifra;
        int error;
@@ -633,11 +679,11 @@ in6_ifattach_loopback(ifp)
  * when ifp == NULL, the caller is responsible for filling scopeid.
  */
 int
-in6_nigroup(ifp, name, namelen, in6)
-       struct ifnet *ifp;
-       const char *name;
-       int namelen;
-       struct in6_addr *in6;
+in6_nigroup(
+       struct ifnet *ifp,
+       const char *name,
+       int namelen,
+       struct in6_addr *in6)
 {
        const char *p;
        u_char *q;
@@ -657,7 +703,7 @@ in6_nigroup(ifp, name, namelen, in6)
        l = p - name;
        strncpy(n, name, l);
        n[(int)l] = '\0';
-       for (q = n; *q; q++) {
+       for (q = (u_char *) n; *q; q++) {
                if ('A' <= *q && *q <= 'Z')
                        *q = *q - 'A' + 'a';
        }
@@ -680,9 +726,9 @@ in6_nigroup(ifp, name, namelen, in6)
 }
 
 void
-in6_nigroup_attach(name, namelen)
-       const char *name;
-       int namelen;
+in6_nigroup_attach(
+       const char *name,
+       int namelen)
 {
        struct ifnet *ifp;
        struct sockaddr_in6 mltaddr;
@@ -695,12 +741,14 @@ in6_nigroup_attach(name, namelen)
        if (in6_nigroup(NULL, name, namelen, &mltaddr.sin6_addr) != 0)
                return;
 
-       for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_list.tqe_next)
-       {
+       ifnet_head_lock_shared();
+       TAILQ_FOREACH(ifp, &ifnet_head, if_list) {
                mltaddr.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
+               ifnet_lock_shared(ifp);
                IN6_LOOKUP_MULTI(mltaddr.sin6_addr, ifp, in6m);
+               ifnet_lock_done(ifp);
                if (!in6m) {
-                       if (!in6_addmulti(&mltaddr.sin6_addr, ifp, &error)) {
+                       if (!in6_addmulti(&mltaddr.sin6_addr, ifp, &error, 0)) {
                                nd6log((LOG_ERR, "%s: failed to join %s "
                                    "(errno=%d)\n", if_name(ifp),
                                    ip6_sprintf(&mltaddr.sin6_addr), 
@@ -708,12 +756,13 @@ in6_nigroup_attach(name, namelen)
                        }
                }
        }
+       ifnet_head_done();
 }
 
 void
-in6_nigroup_detach(name, namelen)
-       const char *name;
-       int namelen;
+in6_nigroup_detach(
+       const char *name,
+       int namelen)
 {
        struct ifnet *ifp;
        struct sockaddr_in6 mltaddr;
@@ -725,13 +774,16 @@ in6_nigroup_detach(name, namelen)
        if (in6_nigroup(NULL, name, namelen, &mltaddr.sin6_addr) != 0)
                return;
 
-       for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_list.tqe_next)
-       {
+       ifnet_head_lock_shared();
+       TAILQ_FOREACH(ifp, &ifnet_head, if_list) {
                mltaddr.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
+               ifnet_lock_shared(ifp);
                IN6_LOOKUP_MULTI(mltaddr.sin6_addr, ifp, in6m);
+               ifnet_lock_done(ifp);
                if (in6m)
-                       in6_delmulti(in6m);
+                       in6_delmulti(in6m, 0);
        }
+       ifnet_head_done();
 }
 
 /*
@@ -740,16 +792,15 @@ in6_nigroup_detach(name, namelen)
  * XXX multiple link-local address case
  */
 void
-in6_ifattach(ifp, altifp, ifra)
-       struct ifnet *ifp;
-       struct ifnet *altifp;   /* secondary EUI64 source */
-       struct  in6_aliasreq *ifra;
+in6_ifattach(
+       struct ifnet *ifp,
+       struct ifnet *altifp,   /* secondary EUI64 source */
+       struct  in6_aliasreq *ifra)
 {
        static size_t if_indexlim = 8;
        struct in6_ifaddr *ia;
        struct in6_addr in6;
 
-
        /*
         * We have some arrays that should be indexed by if_index.
         * since if_index will grow dynamically, they should grow too.
@@ -830,10 +881,18 @@ in6_ifattach(ifp, altifp, ifra)
         * XXX multiple loopback interface case.
         */
        if ((ifp->if_flags & IFF_LOOPBACK) != 0) {
-               in6 = in6addr_loopback;
-               if (in6ifa_ifpwithaddr(ifp, &in6) == NULL) {
-                       if (in6_ifattach_loopback(ifp) != 0)
-                               return;
+               struct in6_ifaddr *ia6 = NULL;
+               if (!OSCompareAndSwap(0, 1, (UInt32 *)&loopattach6_done)) {
+                       in6 = in6addr_loopback;
+                       if ((ia6 = in6ifa_ifpwithaddr(ifp, &in6)) == NULL) {
+                               if (in6_ifattach_loopback(ifp) != 0) {
+                                       OSCompareAndSwap(1, 0, (UInt32 *)&loopattach6_done);
+                                       return;
+                               }
+                       }
+                       else {
+                               ifafree(&ia6->ia_ifa);
+                       }
                }
        }
 
@@ -880,16 +939,14 @@ statinit:
  * from the ifnet list in bsdi.
  */
 void
-in6_ifdetach(ifp)
-       struct ifnet *ifp;
+in6_ifdetach(
+       struct ifnet *ifp)
 {
-       struct in6_ifaddr *ia, *oia;
+       struct in6_ifaddr *ia, *oia, *nia;
        struct ifaddr *ifa, *next;
        struct rtentry *rt;
        short rtflags;
        struct sockaddr_in6 sin6;
-       struct in6_multi *in6m;
-       struct in6_multi *in6m_next;
 
        /* nuke prefix list.  this may try to remove some of ifaddrs as well */
        in6_purgeprefix(ifp);
@@ -898,13 +955,17 @@ in6_ifdetach(ifp)
        nd6_purge(ifp);
 
        /* nuke any of IPv6 addresses we have */
-       for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = next)
-       {
-               next = ifa->ifa_list.tqe_next;
-               if (ifa->ifa_addr->sa_family != AF_INET6)
+       
+       lck_mtx_lock(nd6_mutex);
+       for (ia = in6_ifaddrs; ia != NULL; ia = nia) {
+               nia = ia->ia_next;
+               if (ia->ia_ifa.ifa_ifp != ifp)
                        continue;
-               in6_purgeaddr(ifa);
+               in6_purgeaddr(&ia->ia_ifa, 1);
        }
+       lck_mtx_unlock(nd6_mutex);
+
+       ifnet_lock_exclusive(ifp);
 
        /* undo everything done by in6_ifattach(), just in case */
        for (ifa = ifp->if_addrlist.tqh_first; ifa; ifa = next)
@@ -920,25 +981,28 @@ in6_ifdetach(ifp)
                ia = (struct in6_ifaddr *)ifa;
 
                /* remove from the routing table */
-               if ((ia->ia_flags & IFA_ROUTE)
-                && (rt = rtalloc1((struct sockaddr *)&ia->ia_addr, 0, 0UL))) {
+               lck_mtx_lock(rt_mtx);
+               if ((ia->ia_flags & IFA_ROUTE) &&
+                   (rt = rtalloc1_locked((struct sockaddr *)&ia->ia_addr, 0, 0UL))) {
                        rtflags = rt->rt_flags;
-                       rtfree(rt);
-                       rtrequest(RTM_DELETE,
+                       rtfree_locked(rt);
+                       rtrequest_locked(RTM_DELETE,
                                (struct sockaddr *)&ia->ia_addr,
                                (struct sockaddr *)&ia->ia_addr,
                                (struct sockaddr *)&ia->ia_prefixmask,
                                rtflags, (struct rtentry **)0);
                }
+               lck_mtx_unlock(rt_mtx);
 
                /* remove from the linked list */
-               TAILQ_REMOVE(&ifp->if_addrlist, (struct ifaddr *)ia, ifa_list);
+               if_detach_ifa(ifp, &ia->ia_ifa);
                ifafree(&ia->ia_ifa);
 
                /* also remove from the IPv6 address chain(itojun&jinmei) */
                oia = ia;
-               if (oia == (ia = in6_ifaddr))
-                       in6_ifaddr = ia->ia_next;
+               lck_mtx_lock(nd6_mutex);
+               if (oia == (ia = in6_ifaddrs))
+                       in6_ifaddrs = ia->ia_next;
                else {
                        while (ia->ia_next && (ia->ia_next != oia))
                                ia = ia->ia_next;
@@ -950,27 +1014,11 @@ in6_ifdetach(ifp)
                                    "list\n", if_name(ifp)));
                        }
                }
+               lck_mtx_unlock(nd6_mutex);
 
-               IFAFREE(&oia->ia_ifa);
-       }
-
-#ifndef __APPLE__
-
-/*             This is a cause for reentrency, as those multicast addresses are
- *             freed both from the interface detaching and triggered by the closing of the socket
- *             Let the socket do the cleanup and not force it from the interface level
- */
-       /* leave from all multicast groups joined */
-       in6_pcbpurgeif0(LIST_FIRST(udbinfo.listhead), ifp);
-       in6_pcbpurgeif0(LIST_FIRST(ripcbinfo.listhead), ifp);
-       for (in6m = LIST_FIRST(&in6_multihead); in6m; in6m = in6m_next) {
-               in6m_next = LIST_NEXT(in6m, in6m_entry);
-               if (in6m->in6m_ifp != ifp)
-                       continue;
-               in6_delmulti(in6m);
-               in6m = NULL;
+               ifafree(&oia->ia_ifa);
        }
-#endif /* __APPLE__ */
+       ifnet_lock_done(ifp);
 
        /*
         * remove neighbor management table.  we call it twice just to make
@@ -988,20 +1036,24 @@ in6_ifdetach(ifp)
        sin6.sin6_family = AF_INET6;
        sin6.sin6_addr = in6addr_linklocal_allnodes;
        sin6.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
-       rt = rtalloc1((struct sockaddr *)&sin6, 0, 0UL);
-       if (rt && rt->rt_ifp == ifp) {
-               rtrequest(RTM_DELETE, (struct sockaddr *)rt_key(rt),
-                       rt->rt_gateway, rt_mask(rt), rt->rt_flags, 0);
-               rtfree(rt);
+       lck_mtx_lock(rt_mtx);
+       rt = rtalloc1_locked((struct sockaddr *)&sin6, 0, 0UL);
+       if (rt != NULL) {
+               if (rt->rt_ifp == ifp) {
+                       rtrequest_locked(RTM_DELETE, (struct sockaddr *)rt_key(rt),
+                               rt->rt_gateway, rt_mask(rt), rt->rt_flags, 0);
+               }
+               rtfree_locked(rt);
        }
+       lck_mtx_unlock(rt_mtx);
 }
 
 void
-in6_get_tmpifid(ifp, retbuf, baseid, generate)
-       struct ifnet *ifp;
-       u_int8_t *retbuf;
-       const u_int8_t *baseid;
-       int generate;
+in6_get_tmpifid(
+       struct ifnet *ifp,
+       u_int8_t *retbuf,
+       const u_int8_t *baseid,
+       int generate)
 {
        u_int8_t nullbuf[8];
        struct nd_ifinfo *ndi = &nd_ifinfo[ifp->if_index];
@@ -1022,45 +1074,35 @@ in6_get_tmpifid(ifp, retbuf, baseid, generate)
        bcopy(ndi->randomid, retbuf, 8);
 }
 
-void 
-in6_tmpaddrtimer_funneled(void *ignored_arg)
-{
-#ifdef __APPLE__
-        boolean_t   funnel_state;
-        funnel_state = thread_funnel_set(network_flock, TRUE);
-#endif
-        in6_tmpaddrtimer(ignored_arg); 
-#ifdef __APPLE__
-        (void) thread_funnel_set(network_flock, FALSE);
-#endif 
-}
-
+extern size_t nd_ifinfo_indexlim;
 void
-in6_tmpaddrtimer(ignored_arg)
-       void *ignored_arg;
+in6_tmpaddrtimer(
+       __unused void *ignored_arg)
 {
        int i;
        struct nd_ifinfo *ndi;
        u_int8_t nullbuf[8];
-       int s = splnet();
 
-       timeout(in6_tmpaddrtimer_funneled, (caddr_t)0,
+       timeout(in6_tmpaddrtimer, (caddr_t)0,
                      (ip6_temp_preferred_lifetime - ip6_desync_factor -
                       ip6_temp_regen_advance) * hz);
 
-       bzero(nullbuf, sizeof(nullbuf));
-       for (i = 1; i < if_index + 1; i++) {
-               ndi = &nd_ifinfo[i];
-               if (bcmp(ndi->randomid, nullbuf, sizeof(nullbuf)) != 0) {
-                       /*
-                        * We've been generating a random ID on this interface.
-                        * Create a new one.
-                        */
-                       (void)generate_tmp_ifid(ndi->randomseed0,
-                                               ndi->randomseed1,
-                                               ndi->randomid);
+       if (ip6_use_tempaddr) {
+               
+               bzero(nullbuf, sizeof(nullbuf));
+               for (i = 1; i < nd_ifinfo_indexlim + 1; i++) {
+                       ndi = &nd_ifinfo[i];
+                       if (ndi->flags != ND6_IFF_PERFORMNUD)
+                               continue;
+                       if (bcmp(ndi->randomid, nullbuf, sizeof(nullbuf)) != 0) {
+                               /*
+                                * We've been generating a random ID on this interface.
+                                * Create a new one.
+                                */
+                               (void)generate_tmp_ifid(ndi->randomseed0,
+                                                       ndi->randomseed1,
+                                                       ndi->randomid);
+                       }
                }
        }
-
-       splx(s);
 }