*if_afdata[] and struct domain's dom_if{at,de}tach() are only used with
IPv6 Neighbour Discovery in6_dom{at,de}tach(), which allocate/init and
free single struct nd_ifinfo.

Set up a new ND-specific *if_nd member directly to avoid yet another
layer of indirection and thus make the generic domain API obsolete.

The per-interface data is only accessed in nd6.c and nd6_nbr.c through
the ND_IFINFO() macro;  it is allocated and freed exactly once during
interface at/detach, so document it as [I]mmutable.

Next up as separate commits:
- remove *if_afdata[] struct domain's dom_if{at,de}tach()
- nd6_if{at,de}tach() return/argument type cleanup
- inline ND_IFINFO()

Feedback? Objection? OK?

diff --git a/sys/net/if.c b/sys/net/if.c
index f3fba33de3f..bdaa41aea9f 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -453,16 +453,25 @@ if_idxmap_remove(struct ifnet *ifp)
  */
 void
 if_attachsetup(struct ifnet *ifp)
 {
        unsigned long ifidx;
+#ifdef INET6
+       int s;
+#endif
 
        NET_ASSERT_LOCKED();
 
        if_addgroup(ifp, IFG_ALL);
 
        if_attachdomain(ifp);
+#ifdef INET6
+       s = splnet();
+       ifp->if_nd = nd6_ifattach(ifp);
+       splx(s);
+#endif
+
 #if NPF > 0
        pfi_attach_ifnet(ifp);
 #endif
 
        timeout_set(&ifp->if_slowtimo, if_slowtimo, ifp);
@@ -1125,10 +1134,13 @@ if_detach(struct ifnet *ifp)
        for (i = 0; (dp = domains[i]) != NULL; i++) {
                if (dp->dom_ifdetach && ifp->if_afdata[dp->dom_family])
                        (*dp->dom_ifdetach)(ifp,
                            ifp->if_afdata[dp->dom_family]);
        }
+#ifdef INET6
+       nd6_ifdetach(ifp->if_nd);
+#endif
 
        /* Announce that the interface is gone. */
        rtm_ifannounce(ifp, IFAN_DEPARTURE);
        splx(s);
        NET_UNLOCK();
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
index 3a418bf0547..3bf07ed3071 100644
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -185,10 +185,11 @@ struct ifnet {                            /* and the 
entries */
        unsigned int if_niqs;           /* [I] number of input queues */
 
        struct sockaddr_dl *if_sadl;    /* [N] pointer to our sockaddr_dl */
 
        void    *if_afdata[AF_MAX];
+       struct  nd_ifinfo *if_nd;       /* [I] IPv6 Neighour Discovery info */
 };
 #define        if_mtu          if_data.ifi_mtu
 #define        if_type         if_data.ifi_type
 #define        if_addrlen      if_data.ifi_addrlen
 #define        if_hdrlen       if_data.ifi_hdrlen
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index 7971f79f44c..3fe9386f8af 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -1595,17 +1595,5 @@ in6if_do_dad(struct ifnet *ifp)
                        return (0);
 
                return (1);
        }
 }
-
-void *
-in6_domifattach(struct ifnet *ifp)
-{
-       return nd6_ifattach(ifp);
-}
-
-void
-in6_domifdetach(struct ifnet *ifp, void *aux)
-{
-       nd6_ifdetach(aux);
-}
diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c
index 808422f6eab..e302f39cddf 100644
--- a/sys/netinet6/in6_proto.c
+++ b/sys/netinet6/in6_proto.c
@@ -336,12 +336,10 @@ const struct domain inet6domain = {
   .dom_protosw = inet6sw,
   .dom_protoswNPROTOSW = &inet6sw[nitems(inet6sw)],
   .dom_sasize = sizeof(struct sockaddr_in6),
   .dom_rtoffset = offsetof(struct sockaddr_in6, sin6_addr),
   .dom_maxplen = 128,
-  .dom_ifattach = in6_domifattach,
-  .dom_ifdetach = in6_domifdetach
 };
 
 /*
  * Internet configuration info
  */
diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h
index f6920137cea..1bbbc5f9e23 100644
--- a/sys/netinet6/nd6.h
+++ b/sys/netinet6/nd6.h
@@ -75,11 +75,11 @@ struct      in6_ndireq {
 #ifdef _KERNEL
 
 #include <sys/queue.h>
 
 #define ND_IFINFO(ifp) \
-       ((struct nd_ifinfo *)(ifp)->if_afdata[AF_INET6])
+       ((ifp)->if_nd)
 
 struct llinfo_nd6 {
        TAILQ_ENTRY(llinfo_nd6) ln_list;
        struct  rtentry *ln_rt;
        struct  mbuf *ln_hold;  /* last packet until resolved/timeout */

Reply via email to