On Tue, Aug 27, 2013 at 03:38:49PM +0200, Martin Pieuchot wrote:
> 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?

That makes soooo much more sense. :-).

ok krw@ (note: not a routing table guru!)

.... Ken

> 
> 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