Diff below remove the last use of the global IPv4 list of addresses.

The code using it is a hack to move the unique cloning route of a
subnet from one ifa to another.  I know a proper fix would be to use
multipath for that, but this is not possible feasible right now
because we cannot select multipath route entries based on a different
ifa.

In the meantime this allow us to simplify in_ifinit() which still needs
better error handling.

ok?

Index: netinet/in.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/in.c,v
retrieving revision 1.114
diff -u -p -r1.114 in.c
--- netinet/in.c        5 Jan 2015 10:21:58 -0000       1.114
+++ netinet/in.c        6 Jan 2015 11:36:28 -0000
@@ -607,9 +607,6 @@ in_ifinit(struct ifnet *ifp, struct in_i
 
        splsoftassert(IPL_SOFTNET);
 
-       if (newaddr)
-               TAILQ_INSERT_TAIL(&in_ifaddr, ia, ia_list);
-
        /*
         * Always remove the address from the tree to make sure its
         * position gets updated in case the key changes.
@@ -629,9 +626,18 @@ in_ifinit(struct ifnet *ifp, struct in_i
        if (ifp->if_ioctl &&
            (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia))) {
                ia->ia_addr = oldaddr;
-               goto out;
        }
 
+       /*
+        * Add the address to the local list and the global tree.  If an
+        * error occured, put back the original address.
+        */
+       ifa_add(ifp, &ia->ia_ifa);
+       rt_ifa_addlocal(&ia->ia_ifa);
+
+       if (error)
+               goto out;
+
        if (ia->ia_netmask == 0) {
                if (IN_CLASSA(i))
                        ia->ia_netmask = IN_CLASSA_NET;
@@ -678,18 +684,6 @@ in_ifinit(struct ifnet *ifp, struct in_i
        }
 
 out:
-       /*
-        * Add the address to the local list and the global tree
-        * even if an error occured to make sure the various
-        * global structures are consistent.
-        *
-        * XXX This is necessary because we added the address
-        * to the global list in the first place because of
-        * carp(4).
-        */
-       ifa_add(ifp, &ia->ia_ifa);
-       rt_ifa_addlocal(&ia->ia_ifa);
-
        if (error && newaddr)
                in_purgeaddr(&ia->ia_ifa);
 
@@ -709,7 +703,6 @@ in_purgeaddr(struct ifaddr *ifa)
        rt_ifa_dellocal(&ia->ia_ifa);
        ifa_del(ifp, &ia->ia_ifa);
 
-       TAILQ_REMOVE(&in_ifaddr, ia, ia_list);
        if (ia->ia_allhosts != NULL) {
                in_delmulti(ia->ia_allhosts);
                ia->ia_allhosts = NULL;
@@ -775,6 +768,8 @@ in_remove_prefix(struct in_ifaddr *ia)
 int
 in_addprefix(struct in_ifaddr *ia0)
 {
+       struct ifnet *ifp;
+       struct ifaddr *ifa;
        struct in_ifaddr *ia;
        struct in_addr prefix, mask, p, m;
 
@@ -782,36 +777,44 @@ in_addprefix(struct in_ifaddr *ia0)
        mask = ia0->ia_sockmask.sin_addr;
        prefix.s_addr &= mask.s_addr;
 
-       TAILQ_FOREACH(ia, &in_ifaddr, ia_list) {
-               if (ia->ia_ifp->if_rdomain != ia0->ia_ifp->if_rdomain)
-                       continue;
-
-               if ((ia->ia_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)))
+       TAILQ_FOREACH(ifp, &ifnet, if_list) {
+               if (ifp->if_flags & (IFF_LOOPBACK|IFF_POINTOPOINT))
                        continue;
 
-               if ((ia->ia_flags & IFA_ROUTE) == 0)
+               if (ifp->if_rdomain != ia0->ia_ifp->if_rdomain)
                        continue;
 
-               p = ia->ia_addr.sin_addr;
-               m = ia->ia_sockmask.sin_addr;
-               p.s_addr &= m.s_addr;
-
-               if (prefix.s_addr != p.s_addr || mask.s_addr != m.s_addr)
-                       continue;
+               TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
+                       if (ifa->ifa_addr->sa_family != AF_INET)
+                               continue;
+
+                       ia = ifatoia(ifa);
+
+                       if ((ia->ia_flags & IFA_ROUTE) == 0)
+                               continue;
+
+                       p = ia->ia_addr.sin_addr;
+                       m = ia->ia_sockmask.sin_addr;
+                       p.s_addr &= m.s_addr;
+
+                       if (prefix.s_addr != p.s_addr ||
+                           mask.s_addr != m.s_addr)
+                               continue;
 
 #if NCARP > 0
-               /* move to a real interface instead of carp interface */
-               if (ia->ia_ifp->if_type == IFT_CARP &&
-                   ia0->ia_ifp->if_type != IFT_CARP) {
-                       in_remove_prefix(ia);
-                       break;
-               }
+                       /* move to a real interface instead of carp interface */
+                       if (ia->ia_ifp->if_type == IFT_CARP &&
+                           ia0->ia_ifp->if_type != IFT_CARP) {
+                               in_remove_prefix(ia);
+                               break;
+                       }
 #endif
-               /*
-                * if we got a matching prefix route inserted by other
-                * interface address, we don't need to bother
-                */
-               return 0;
+                       /*
+                        * If we got a matching prefix route inserted by other
+                        * interface address, we don't need to bother
+                        */
+                       return (0);
+               }
        }
 
        /*
@@ -828,6 +831,8 @@ in_addprefix(struct in_ifaddr *ia0)
 int
 in_scrubprefix(struct in_ifaddr *ia0)
 {
+       struct ifnet *ifp;
+       struct ifaddr *ifa;
        struct in_ifaddr *ia;
        struct in_addr prefix, mask, p, m;
 
@@ -838,28 +843,34 @@ in_scrubprefix(struct in_ifaddr *ia0)
        mask = ia0->ia_sockmask.sin_addr;
        prefix.s_addr &= mask.s_addr;
 
-       TAILQ_FOREACH(ia, &in_ifaddr, ia_list) {
-               if (ia->ia_ifp->if_rdomain != ia0->ia_ifp->if_rdomain)
-                       continue;
-
-               if ((ia->ia_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)))
+       TAILQ_FOREACH(ifp, &ifnet, if_list) {
+               if (ifp->if_flags & (IFF_LOOPBACK|IFF_POINTOPOINT))
                        continue;
 
-               if ((ia->ia_flags & IFA_ROUTE) != 0)
+               if (ifp->if_rdomain != ia0->ia_ifp->if_rdomain)
                        continue;
 
-               p = ia->ia_addr.sin_addr;
-               m = ia->ia_sockmask.sin_addr;
-               p.s_addr &= m.s_addr;
-
-               if (prefix.s_addr != p.s_addr || mask.s_addr != m.s_addr)
-                       continue;
-
-               /*
-                * if we got a matching prefix route, move IFA_ROUTE to him
-                */
-               in_remove_prefix(ia0);
-               return in_insert_prefix(ia);
+               TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
+                       if (ifa->ifa_addr->sa_family != AF_INET)
+                               continue;
+
+                       ia = ifatoia(ifa);
+
+                       if ((ia->ia_flags & IFA_ROUTE) != 0)
+                               continue;
+
+                       p = ia->ia_addr.sin_addr;
+                       m = ia->ia_sockmask.sin_addr;
+                       p.s_addr &= m.s_addr;
+
+                       if (prefix.s_addr != p.s_addr ||
+                           mask.s_addr != m.s_addr)
+                               continue;
+
+                       /* Move IFA_ROUTE to the matching prefix route. */
+                       in_remove_prefix(ia0);
+                       return (in_insert_prefix(ia));
+               }
        }
 
        /*
Index: netinet/in_var.h
===================================================================
RCS file: /home/ncvs/src/sys/netinet/in_var.h,v
retrieving revision 1.34
diff -u -p -r1.34 in_var.h
--- netinet/in_var.h    27 Mar 2014 10:39:23 -0000      1.34
+++ netinet/in_var.h    6 Jan 2015 11:36:28 -0000
@@ -77,9 +77,6 @@ struct        in_aliasreq {
 
 
 #ifdef _KERNEL
-TAILQ_HEAD(in_ifaddrhead, in_ifaddr);
-extern struct  in_ifaddrhead in_ifaddr;
-
 /*
  * Macro for finding the internet address structure (in_ifaddr) corresponding
  * to a given interface (ifnet structure).
Index: netinet/ip_input.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ip_input.c,v
retrieving revision 1.243
diff -u -p -r1.243 ip_input.c
--- netinet/ip_input.c  5 Dec 2014 15:50:04 -0000       1.243
+++ netinet/ip_input.c  6 Jan 2015 11:36:28 -0000
@@ -114,7 +114,6 @@ int ip_frags = 0;
 
 int *ipctl_vars[IPCTL_MAXID] = IPCTL_VARS;
 
-struct in_ifaddrhead in_ifaddr;
 struct ifqueue ipintrq;
 
 struct pool ipqent_pool;
@@ -172,7 +171,6 @@ ip_init(void)
                        ip_protox[pr->pr_protocol] = pr - inetsw;
        LIST_INIT(&ipq);
        IFQ_SET_MAXLEN(&ipintrq, IFQ_MAXLEN);
-       TAILQ_INIT(&in_ifaddr);
        if (ip_mtudisc != 0)
                ip_mtudisc_timeout_q =
                    rt_timer_queue_create(ip_mtudisc_timeout);

Reply via email to