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