So I started to play with the routine table and I'm slowly trying to
unify the various code paths to add and delete route entries.  The 
diff below is a first step, it splits rtinit() into rt_add() and
rt_delete() there should be no functional change.

ok?

Index: net/if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.262
diff -u -p -r1.262 if.c
--- net/if.c    20 Aug 2013 09:14:22 -0000      1.262
+++ net/if.c    27 Aug 2013 13:33:03 -0000
@@ -353,7 +353,7 @@ if_free_sadl(struct ifnet *ifp)
                return;
 
        s = splnet();
-       rtinit(ifa, RTM_DELETE, 0);
+       rt_del(ifa, 0);
 #if 0
        ifa_del(ifp, ifa);
        ifp->if_lladdr = NULL;
Index: net/route.c
===================================================================
RCS file: /cvs/src/sys/net/route.c,v
retrieving revision 1.144
diff -u -p -r1.144 route.c
--- net/route.c 28 Mar 2013 23:10:05 -0000      1.144
+++ net/route.c 27 Aug 2013 13:33:03 -0000
@@ -1069,11 +1069,10 @@ rt_maskedcopy(struct sockaddr *src, stru
  * for an interface.
  */
 int
-rtinit(struct ifaddr *ifa, int cmd, int flags)
+rt_add(struct ifaddr *ifa, int flags)
 {
        struct rtentry          *rt;
-       struct sockaddr         *dst, *deldst;
-       struct mbuf             *m = NULL;
+       struct sockaddr         *dst;
        struct rtentry          *nrt = NULL;
        int                      error;
        struct rt_addrinfo       info;
@@ -1081,35 +1080,11 @@ rtinit(struct ifaddr *ifa, int cmd, int 
        u_short                  rtableid = ifa->ifa_ifp->if_rdomain;
 
        dst = flags & RTF_HOST ? ifa->ifa_dstaddr : ifa->ifa_addr;
-       if (cmd == RTM_DELETE) {
-               if ((flags & RTF_HOST) == 0 && ifa->ifa_netmask) {
-                       m = m_get(M_DONTWAIT, MT_SONAME);
-                       if (m == NULL)
-                               return (ENOBUFS);
-                       deldst = mtod(m, struct sockaddr *);
-                       rt_maskedcopy(dst, deldst, ifa->ifa_netmask);
-                       dst = deldst;
-               }
-               if ((rt = rtalloc1(dst, 0, rtableid)) != NULL) {
-                       rt->rt_refcnt--;
-                       /* try to find the right route */
-                       while (rt && rt->rt_ifa != ifa)
-                               rt = (struct rtentry *)
-                                   ((struct radix_node *)rt)->rn_dupedkey;
-                       if (!rt) {
-                               if (m != NULL)
-                                       (void) m_free(m);
-                               return (flags & RTF_HOST ? EHOSTUNREACH
-                                                       : ENETUNREACH);
-                       }
-               }
-       }
        bzero(&info, sizeof(info));
        info.rti_ifa = ifa;
        info.rti_flags = flags | ifa->ifa_flags;
        info.rti_info[RTAX_DST] = dst;
-       if (cmd == RTM_ADD)
-               info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr;
+       info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr;
        info.rti_info[RTAX_LABEL] =
            rtlabel_id2sa(ifa->ifa_ifp->if_rtlabelid, &sa_rl);
 
@@ -1120,22 +1095,11 @@ rtinit(struct ifaddr *ifa, int cmd, int 
         * change it to meet bsdi4 behavior.
         */
        info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask;
-       error = rtrequest1(cmd, &info, RTP_CONNECTED, &nrt, rtableid);
-       if (cmd == RTM_DELETE) {
-               if (error == 0 && (rt = nrt) != NULL) {
-                       rt_newaddrmsg(cmd, ifa, error, nrt);
-                       if (rt->rt_refcnt <= 0) {
-                               rt->rt_refcnt++;
-                               rtfree(rt);
-                       }
-               }
-               if (m != NULL)
-                       (void) m_free(m);
-       }
-       if (cmd == RTM_ADD && error == 0 && (rt = nrt) != NULL) {
+       error = rtrequest1(RTM_ADD, &info, RTP_CONNECTED, &nrt, rtableid);
+       if (error == 0 && (rt = nrt) != NULL) {
                rt->rt_refcnt--;
                if (rt->rt_ifa != ifa) {
-                       printf("rtinit: wrong ifa (%p) was (%p)\n",
+                       printf("%s: wrong ifa (%p) was (%p)\n", __func__,
                            ifa, rt->rt_ifa);
                        if (rt->rt_ifa->ifa_rtrequest)
                                rt->rt_ifa->ifa_rtrequest(RTM_DELETE, rt, NULL);
@@ -1146,8 +1110,68 @@ rtinit(struct ifaddr *ifa, int cmd, int 
                        if (ifa->ifa_rtrequest)
                                ifa->ifa_rtrequest(RTM_ADD, rt, NULL);
                }
-               rt_newaddrmsg(cmd, ifa, error, nrt);
+               rt_newaddrmsg(RTM_ADD, ifa, error, nrt);
+       }
+
+       return (error);
+}
+
+int
+rt_del(struct ifaddr *ifa, int flags)
+{
+       struct rtentry          *rt;
+       struct sockaddr         *dst, *deldst;
+       struct mbuf             *m = NULL;
+       struct rtentry          *nrt = NULL;
+       int                      error;
+       struct rt_addrinfo       info;
+       u_short                  rtableid = ifa->ifa_ifp->if_rdomain;
+
+       dst = flags & RTF_HOST ? ifa->ifa_dstaddr : ifa->ifa_addr;
+       if ((flags & RTF_HOST) == 0 && ifa->ifa_netmask) {
+               m = m_get(M_DONTWAIT, MT_SONAME);
+               if (m == NULL)
+                       return (ENOBUFS);
+               deldst = mtod(m, struct sockaddr *);
+               rt_maskedcopy(dst, deldst, ifa->ifa_netmask);
+               dst = deldst;
        }
+       if ((rt = rtalloc1(dst, 0, rtableid)) != NULL) {
+               rt->rt_refcnt--;
+               /* try to find the right route */
+               while (rt && rt->rt_ifa != ifa)
+                       rt = (struct rtentry *)
+                           ((struct radix_node *)rt)->rn_dupedkey;
+               if (!rt) {
+                       if (m != NULL)
+                               m_free(m);
+                       return (flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
+               }
+       }
+
+       bzero(&info, sizeof(info));
+       info.rti_ifa = ifa;
+       info.rti_flags = flags | ifa->ifa_flags;
+       info.rti_info[RTAX_DST] = dst;
+
+       /*
+        * XXX here, it seems that we are assuming that ifa_netmask is NULL
+        * for RTF_HOST.  bsdi4 passes NULL explicitly (via intermediate
+        * variable) when RTF_HOST is 1.  still not sure if i can safely
+        * change it to meet bsdi4 behavior.
+        */
+       info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask;
+       error = rtrequest1(RTM_DELETE, &info, RTP_CONNECTED, &nrt, rtableid);
+       if (error == 0 && (rt = nrt) != NULL) {
+               rt_newaddrmsg(RTM_DELETE, ifa, error, nrt);
+               if (rt->rt_refcnt <= 0) {
+                       rt->rt_refcnt++;
+                       rtfree(rt);
+               }
+       }
+       if (m != NULL)
+               (void) m_free(m);
+
        return (error);
 }
 
Index: net/route.h
===================================================================
RCS file: /cvs/src/sys/net/route.h,v
retrieving revision 1.78
diff -u -p -r1.78 route.h
--- net/route.h 19 Sep 2012 16:14:01 -0000      1.78
+++ net/route.h 27 Aug 2013 13:33:03 -0000
@@ -396,7 +396,8 @@ struct rtentry *
         rtalloc1(struct sockaddr *, int, u_int);
 void    rtfree(struct rtentry *);
 int     rt_getifa(struct rt_addrinfo *, u_int);
-int     rtinit(struct ifaddr *, int, int);
+int     rt_add(struct ifaddr *, int);
+int     rt_del(struct ifaddr *, int);
 int     rtioctl(u_long, caddr_t, struct proc *);
 void    rtredirect(struct sockaddr *, struct sockaddr *,
                         struct sockaddr *, int, struct sockaddr *,
Index: netinet/in.c
===================================================================
RCS file: /cvs/src/sys/netinet/in.c,v
retrieving revision 1.83
diff -u -p -r1.83 in.c
--- netinet/in.c        19 Aug 2013 08:45:34 -0000      1.83
+++ netinet/in.c        27 Aug 2013 13:33:04 -0000
@@ -323,9 +323,9 @@ in_control(struct socket *so, u_long cmd
                }
                if (ia->ia_flags & IFA_ROUTE) {
                        ia->ia_ifa.ifa_dstaddr = sintosa(&oldaddr);
-                       rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
+                       rt_del(&ia->ia_ifa, RTF_HOST);
                        ia->ia_ifa.ifa_dstaddr = sintosa(&ia->ia_dstaddr);
-                       rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
+                       rt_add(&ia->ia_ifa, RTF_HOST | RTF_UP);
                }
                splx(s);
                break;
@@ -777,8 +777,7 @@ in_addprefix(struct in_ifaddr *target, i
                /* move to a real interface instead of carp interface */
                if (ia->ia_ifp->if_type == IFT_CARP &&
                    target->ia_ifp->if_type != IFT_CARP) {
-                       rtinit(&(ia->ia_ifa), (int)RTM_DELETE,
-                           rtinitflags(ia));
+                       rt_del(&ia->ia_ifa, rtinitflags(ia));
                        ia->ia_flags &= ~IFA_ROUTE;
                        break;
                }
@@ -793,7 +792,7 @@ in_addprefix(struct in_ifaddr *target, i
        /*
         * noone seem to have prefix route.  insert it.
         */
-       error = rtinit(&target->ia_ifa, (int)RTM_ADD, flags);
+       error = rt_add(&target->ia_ifa, flags);
        if (!error)
                target->ia_flags |= IFA_ROUTE;
        return error;
@@ -842,12 +841,10 @@ in_scrubprefix(struct in_ifaddr *target)
                 * if we got a matching prefix route, move IFA_ROUTE to him
                 */
                if ((ia->ia_flags & IFA_ROUTE) == 0) {
-                       rtinit(&(target->ia_ifa), (int)RTM_DELETE,
-                           rtinitflags(target));
+                       rt_del(&target->ia_ifa, rtinitflags(target));
                        target->ia_flags &= ~IFA_ROUTE;
 
-                       error = rtinit(&ia->ia_ifa, (int)RTM_ADD,
-                           rtinitflags(ia) | RTF_UP);
+                       error = rt_add(&ia->ia_ifa, rtinitflags(ia) | RTF_UP);
                        if (error == 0)
                                ia->ia_flags |= IFA_ROUTE;
                        return error;
@@ -857,7 +854,7 @@ in_scrubprefix(struct in_ifaddr *target)
        /*
         * noone seem to have prefix route.  remove it.
         */
-       rtinit(&(target->ia_ifa), (int)RTM_DELETE, rtinitflags(target));
+       rt_del(&target->ia_ifa, rtinitflags(target));
        target->ia_flags &= ~IFA_ROUTE;
        return 0;
 }
Index: netinet6/in6.c
===================================================================
RCS file: /cvs/src/sys/netinet6/in6.c,v
retrieving revision 1.118
diff -u -p -r1.118 in6.c
--- netinet6/in6.c      26 Aug 2013 07:15:58 -0000      1.118
+++ netinet6/in6.c      27 Aug 2013 13:33:04 -0000
@@ -200,7 +200,7 @@ in6_ifloop_request(int cmd, struct ifadd
 
        /*
         * Report the addition/removal of the address to the routing socket.
-        * XXX: since we called rtinit for a p2p interface with a destination,
+        * XXX: since we called rt_add for a p2p interface with a destination,
         *      we end up reporting twice in such a case.  Should we rather
         *      omit the second report?
         */
@@ -932,7 +932,7 @@ in6_update_ifa(struct ifnet *ifp, struct
                int e;
 
                if ((ia->ia_flags & IFA_ROUTE) != 0 &&
-                   (e = rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST)) != 
0) {
+                   (e = rt_del(&ia->ia_ifa, RTF_HOST)) != 0) {
                        nd6log((LOG_ERR, "in6_update_ifa: failed to remove "
                            "a route to the old destination: %s\n",
                            ip6_sprintf(&ia->ia_addr.sin6_addr)));
@@ -1193,8 +1193,7 @@ in6_purgeaddr(struct ifaddr *ifa)
        if ((ia->ia_flags & IFA_ROUTE) != 0 && ia->ia_dstaddr.sin6_len != 0) {
                int e;
 
-               if ((e = rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST))
-                   != 0) {
+               if ((e = rt_del(&ia->ia_ifa, RTF_HOST)) != 0) {
                        log(LOG_ERR, "in6_purgeaddr: failed to remove "
                            "a route to the p2p destination: %s on %s, "
                            "errno=%d\n",
@@ -1535,8 +1534,7 @@ in6_ifinit(struct ifnet *ifp, struct in6
         */
        plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL); /* XXX */
        if (plen == 128 && ia->ia_dstaddr.sin6_family == AF_INET6) {
-               if ((error = rtinit(&(ia->ia_ifa), (int)RTM_ADD,
-                                   RTF_UP | RTF_HOST)) != 0)
+               if ((error = rt_add(&ia->ia_ifa, RTF_UP | RTF_HOST)) != 0)
                        return (error);
                ia->ia_flags |= IFA_ROUTE;
        }

Reply via email to