...actually we don't even need it for the per-ifp address list!  This is
a result of my recent RTAX_IFP/sadl cleanup. 

Historically the link-layer ifa has been the first element of the
per-ifp address list.  This requirement is no longer necessary since
r1.154 of net/route.c, we now use the if_sadl pointer directly.

Regarding the tree, when Henning added ifa_add/del prior to its addition,
he also used it for link-layer addresses.  But ifa_ifwithaddr() was not
dealing with link-layer addresses at that time!  So when ifa_add/del
got modified to add elements to the tree, all the lladdrs ended up in it.

It's really easy to check that there's no need for such thing.  The only
place where ifa_ifwithaddr() might have an AF_LINK sockaddr, is the 
(in)famous ifa_ifwithrout().  But since this code predates from decades
the RB-tree, I would bet a lot of beers that it does not expect such
ifa.  Plus we no longer have any iteration on the per-ifp address list 
that look for and AF_LINK ifa.

So this diff removes it from the tree and the per-ifp list.  Our stack
is design such that there's a one-to-one mapping between an ifp and its
lladdr.

If you have the sadl do:

        ifp = if_get(sdl->sdl_index);

If you have the ifp do:

        sdl = ifp->if_sadl;


I'm not sure if we really need an "ifa" (struct ifaddr) descriptor for
the lladdr, but that's not really important.

The diff below also set the "ifa_netmask" field to NULL since this is
completely valid and the stack check for it.

ok?

Index: net/if.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if.c,v
retrieving revision 1.286
diff -u -p -r1.286 if.c
--- net/if.c    22 Apr 2014 12:35:00 -0000      1.286
+++ net/if.c    25 Apr 2014 13:15:07 -0000
@@ -322,7 +322,7 @@ if_alloc_sadl(struct ifnet *ifp)
        if (socksize < sizeof(*sdl))
                socksize = sizeof(*sdl);
        socksize = ROUNDUP(socksize);
-       ifasize = sizeof(*ifa) + 2 * socksize;
+       ifasize = sizeof(*ifa) + socksize;
        ifa = malloc(ifasize, M_IFADDR, M_WAITOK|M_ZERO);
        sdl = (struct sockaddr_dl *)(ifa + 1);
        sdl->sdl_len = socksize;
@@ -337,12 +337,7 @@ if_alloc_sadl(struct ifnet *ifp)
        ifa->ifa_rtrequest = link_rtrequest;
        ifa->ifa_addr = (struct sockaddr *)sdl;
        ifp->if_sadl = sdl;
-       sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl);
-       ifa->ifa_netmask = (struct sockaddr *)sdl;
-       sdl->sdl_len = masklen;
-       while (namelen != 0)
-               sdl->sdl_data[--namelen] = 0xff;
-       ifa_add(ifp, ifa);
+       ifa->ifa_netmask = NULL;
 }
 
 /*
@@ -362,7 +357,6 @@ if_free_sadl(struct ifnet *ifp)
 
        s = splnet();
        rt_ifa_del(ifa, 0, ifa->ifa_addr);
-       ifa_del(ifp, ifa);
        ifafree(ifp->if_lladdr);
        ifp->if_lladdr = NULL;
        ifp->if_sadl = NULL;
@@ -1496,11 +1490,6 @@ ifioctl(struct socket *so, u_long cmd, c
 #ifdef INET
                        in_ifdetach(ifp);
 #endif
-                       /*
-                        * Remove sadl from ifa RB tree because rdomain is part
-                        * of the lookup key and re-add it after the switch.
-                        */
-                       ifa_del(ifp, ifp->if_lladdr);
                        splx(s);
                }
 
@@ -1511,9 +1500,6 @@ ifioctl(struct socket *so, u_long cmd, c
 
                /* Add interface to the specified rdomain */
                ifp->if_rdomain = ifr->ifr_rdomainid;
-
-               /* re-add sadl to the ifa RB tree in new rdomain */
-               ifa_add(ifp, ifp->if_lladdr);
                break;
 
        case SIOCAIFGROUP:
@@ -2158,10 +2144,7 @@ sysctl_ifq(int *name, u_int namelen, voi
 void
 ifa_add(struct ifnet *ifp, struct ifaddr *ifa)
 {
-       if (ifa->ifa_addr->sa_family == AF_LINK)
-               TAILQ_INSERT_HEAD(&ifp->if_addrlist, ifa, ifa_list);
-       else
-               TAILQ_INSERT_TAIL(&ifp->if_addrlist, ifa, ifa_list);
+       TAILQ_INSERT_TAIL(&ifp->if_addrlist, ifa, ifa_list);
        ifa_item_insert(ifa->ifa_addr, ifa, ifp);
        if (ifp->if_flags & IFF_BROADCAST && ifa->ifa_broadaddr)
                ifa_item_insert(ifa->ifa_broadaddr, ifa, ifp);
Index: net/rtsock.c
===================================================================
RCS file: /home/ncvs/src/sys/net/rtsock.c,v
retrieving revision 1.142
diff -u -p -r1.142 rtsock.c
--- net/rtsock.c        18 Mar 2014 10:47:34 -0000      1.142
+++ net/rtsock.c        25 Apr 2014 13:15:07 -0000
@@ -1317,8 +1317,7 @@ sysctl_iflist(int af, struct walkarg *w)
                }
                info.rti_info[RTAX_IFP] = NULL;
                TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
-                       if (ifa->ifa_addr->sa_family == AF_LINK)
-                               continue;
+                       KASSERT(ifa->ifa_addr->sa_family != AF_LINK);
                        if (af && af != ifa->ifa_addr->sa_family)
                                continue;
                        info.rti_info[RTAX_IFA] = ifa->ifa_addr;

Reply via email to