Network addresses added to the interface local list thought ifa_add()
are the link-local address and the IPv4/6 ones.

Since if_detach() now calls in_ifdetach(), there should be no address
left on the list apart from the link-layer one at this stage.  So the
diff below removes it directly, there's no need for a loop anymore.

I left a check for safety afterward...

ok?

Index: net/if.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if.c,v
retrieving revision 1.279
diff -u -p -r1.279 if.c
--- net/if.c    28 Nov 2013 10:16:44 -0000      1.279
+++ net/if.c    7 Jan 2014 11:57:09 -0000
@@ -359,12 +359,10 @@ if_free_sadl(struct ifnet *ifp)
 
        s = splnet();
        rtinit(ifa, RTM_DELETE, 0);
-#if 0
        ifa_del(ifp, ifa);
+       ifafree(ifp->if_lladdr);
        ifp->if_lladdr = NULL;
-#endif
        ifp->if_sadl = NULL;
-
        splx(s);
 }
 
@@ -587,27 +585,22 @@ do { \
        if (ISSET(ifp->if_xflags, IFXF_TXREADY))
                TAILQ_REMOVE(&iftxlist, ifp, if_txlist);
 
-       /*
-        * Deallocate private resources.
-        */
-       while ((ifa = TAILQ_FIRST(&ifp->if_addrlist)) != NULL) {
-               ifa_del(ifp, ifa);
-               /* XXX if_free_sadl needs this */
-               if (ifa == ifp->if_lladdr)
-                       continue;
-
-               ifa->ifa_ifp = NULL;
-               ifafree(ifa);
-       }
-
        while ((ifg = TAILQ_FIRST(&ifp->if_groups)) != NULL)
                if_delgroup(ifp, ifg->ifgl_group->ifg_group);
 
        if_free_sadl(ifp);
 
-       ifp->if_lladdr->ifa_ifp = NULL;
-       ifafree(ifp->if_lladdr);
-       ifp->if_lladdr = NULL;
+       /* We should not have any address left at this point. */
+       if (!TAILQ_EMPTY(&ifp->if_addrlist)) {
+#ifdef DIAGNOSTIC
+               printf("%s: address list non empty\n", ifp->if_xname);
+#endif
+               while ((ifa = TAILQ_FIRST(&ifp->if_addrlist)) != NULL) {
+                       ifa_del(ifp, ifa);
+                       ifa->ifa_ifp = NULL;
+                       ifafree(ifa);
+               }
+       }
 
        free(ifp->if_addrhooks, M_TEMP);
        free(ifp->if_linkstatehooks, M_TEMP);

Reply via email to