On Sun, Oct 25, 2015 at 03:22:51PM +0100, Martin Pieuchot wrote: > Instead of having a separate function to check for MPATH conflicts > simply pass the gateway to rtable_insert(). Some regress tests > outputs will need an update as we're now doing one more rtalloc(9) > call in RTM_ADD. > > This is a step towards MPATH by default. > > ok?
Looks good to me. We still return EEXIST so there should be no visible change because of this. > Index: net/route.c > =================================================================== > RCS file: /cvs/src/sys/net/route.c,v > retrieving revision 1.262 > diff -u -p -r1.262 route.c > --- net/route.c 25 Oct 2015 11:58:11 -0000 1.262 > +++ net/route.c 25 Oct 2015 14:14:28 -0000 > @@ -837,15 +837,6 @@ rtrequest1(int req, struct rt_addrinfo * > else > memcpy(ndst, info->rti_info[RTAX_DST], dlen); > > -#ifndef SMALL_KERNEL > - /* Do not permit exactly the same dst/mask/gw pair. */ > - if (rtable_mpath_conflict(tableid, ndst, > - info->rti_info[RTAX_NETMASK], info->rti_info[RTAX_GATEWAY], > - prio, info->rti_flags & RTF_MPATH)) { > - free(ndst, M_RTABLE, dlen); > - return (EEXIST); > - } > -#endif > rt = pool_get(&rtentry_pool, PR_NOWAIT | PR_ZERO); > if (rt == NULL) { > free(ndst, M_RTABLE, dlen); > @@ -953,13 +944,15 @@ rtrequest1(int req, struct rt_addrinfo * > } > > error = rtable_insert(tableid, ndst, > - info->rti_info[RTAX_NETMASK], rt->rt_priority, rt); > + info->rti_info[RTAX_NETMASK], info->rti_info[RTAX_GATEWAY], > + rt->rt_priority, rt); > if (error != 0 && (crt = rtalloc(ndst, 0, tableid)) != NULL) { > /* overwrite cloned route */ > if ((crt->rt_flags & RTF_CLONED) != 0) { > rtdeletemsg(crt, tableid); > error = rtable_insert(tableid, ndst, > info->rti_info[RTAX_NETMASK], > + info->rti_info[RTAX_GATEWAY], > rt->rt_priority, rt); > } > rtfree(crt); > Index: net/rtable.c > =================================================================== > RCS file: /cvs/src/sys/net/rtable.c,v > retrieving revision 1.14 > diff -u -p -r1.14 rtable.c > --- net/rtable.c 22 Oct 2015 17:19:38 -0000 1.14 > +++ net/rtable.c 25 Oct 2015 14:13:57 -0000 > @@ -292,7 +292,8 @@ rtable_match(unsigned int rtableid, stru > > int > rtable_insert(unsigned int rtableid, struct sockaddr *dst, > - struct sockaddr *mask, uint8_t prio, struct rtentry *rt) > + struct sockaddr *mask, struct sockaddr *gateway, uint8_t prio, > + struct rtentry *rt) > { > struct radix_node_head *rnh; > struct radix_node *rn = (struct radix_node *)rt; > @@ -301,6 +302,15 @@ rtable_insert(unsigned int rtableid, str > if (rnh == NULL) > return (EAFNOSUPPORT); > > +#ifndef SMALL_KERNEL > + if (rnh->rnh_multipath) { > + /* Do not permit exactly the same dst/mask/gw pair. */ > + if (rt_mpath_conflict(rnh, dst, mask, gateway, prio, > + ISSET(rt->rt_flags, RTF_MPATH))) > + return (EEXIST); > + } > +#endif > + > rn = rn_addroute(dst, mask, rnh, rn, prio); > if (rn == NULL) > return (ESRCH); > @@ -382,22 +392,6 @@ rtable_mpath_match(unsigned int rtableid > return (rt); > } > > -int > -rtable_mpath_conflict(unsigned int rtableid, struct sockaddr *dst, > - struct sockaddr *mask, struct sockaddr *gateway, uint8_t prio, int > mpathok) > -{ > - struct radix_node_head *rnh; > - > - rnh = rtable_get(rtableid, dst->sa_family); > - if (rnh == NULL) > - return (EAFNOSUPPORT); > - > - if (rnh->rnh_multipath == 0) > - return (0); > - > - return (rt_mpath_conflict(rnh, dst, mask, gateway, prio, mpathok)); > -} > - > /* Gateway selection by Hash-Threshold (RFC 2992) */ > struct rtentry * > rtable_mpath_select(struct rtentry *rt, uint32_t hash) > @@ -526,7 +520,8 @@ rtable_match(unsigned int rtableid, stru > > int > rtable_insert(unsigned int rtableid, struct sockaddr *dst, > - struct sockaddr *mask, uint8_t prio, struct rtentry *rt) > + struct sockaddr *mask, struct sockaddr *gateway, uint8_t prio, > + struct rtentry *rt) > { > #ifndef SMALL_KERNEL > struct rtentry *mrt; > @@ -545,6 +540,29 @@ rtable_insert(unsigned int rtableid, str > if (plen == -1) > return (EINVAL); > > +#ifndef SMALL_KERNEL > + /* Do not permit exactly the same dst/mask/gw pair. */ > + an = art_lookup(ar, addr, plen); > + if (an != NULL && an->an_plen == plen && > + !memcmp(an->an_dst, dst, dst->sa_len)) { > + struct rtentry *mrt; > + int mpathok = ISSET(rt->rt_flags, RTF_MPATH); > + > + LIST_FOREACH(mrt, &an->an_rtlist, rt_next) { > + if (prio != RTP_ANY && > + (mrt->rt_priority & RTP_MASK) != (prio & RTP_MASK)) > + continue; > + > + if (!mpathok) > + return (EEXIST); > + > + if (mrt->rt_gateway->sa_len == gateway->sa_len && > + !memcmp(mrt->rt_gateway, gateway, gateway->sa_len)) > + return (EEXIST); > + } > + } > +#endif > + > an = pool_get(&an_pool, PR_NOWAIT | PR_ZERO); > if (an == NULL) > return (ENOBUFS); > @@ -754,48 +772,6 @@ rtable_mpath_match(unsigned int rtableid > rtfree(rt0); > > return (rt); > -} > - > -int > -rtable_mpath_conflict(unsigned int rtableid, struct sockaddr *dst, > - struct sockaddr *mask, struct sockaddr *gateway, uint8_t prio, int > mpathok) > -{ > - struct art_root *ar; > - struct art_node *an; > - struct rtentry *rt; > - uint8_t *addr; > - int plen; > - > - ar = rtable_get(rtableid, dst->sa_family); > - if (ar == NULL) > - return (EAFNOSUPPORT); > - > - addr = satoaddr(ar, dst); > - plen = satoplen(ar, mask); > - if (plen == -1) > - return (EINVAL); > - > - an = art_lookup(ar, addr, plen); > - /* Make sure we've got a perfect match. */ > - if (an == NULL || an->an_plen != plen || > - memcmp(an->an_dst, dst, dst->sa_len)) > - return (0); > - > - LIST_FOREACH(rt, &an->an_rtlist, rt_next) { > - if (prio != RTP_ANY && > - (rt->rt_priority & RTP_MASK) != (prio & RTP_MASK)) > - continue; > - > - if (!mpathok) > - return (EEXIST); > - > - if (rt->rt_gateway->sa_len == gateway->sa_len && > - memcmp(rt->rt_gateway, gateway, gateway->sa_len) == 0) > - return (EEXIST); > - } > - > - > - return (0); > } > > /* Gateway selection by Hash-Threshold (RFC 2992) */ > Index: net/rtable.h > =================================================================== > RCS file: /cvs/src/sys/net/rtable.h,v > retrieving revision 1.7 > diff -u -p -r1.7 rtable.h > --- net/rtable.h 22 Oct 2015 17:19:38 -0000 1.7 > +++ net/rtable.h 25 Oct 2015 14:13:46 -0000 > @@ -57,7 +57,8 @@ struct rtentry *rtable_lookup(unsigned i > struct sockaddr *); > struct rtentry *rtable_match(unsigned int, struct sockaddr *); > int rtable_insert(unsigned int, struct sockaddr *, > - struct sockaddr *, uint8_t, struct rtentry *); > + struct sockaddr *, struct sockaddr *, uint8_t, > + struct rtentry *); > int rtable_delete(unsigned int, struct sockaddr *, > struct sockaddr *, uint8_t, struct rtentry *); > int rtable_walk(unsigned int, sa_family_t, > @@ -66,8 +67,6 @@ int rtable_walk(unsigned int, sa_famil > int rtable_mpath_capable(unsigned int, sa_family_t); > struct rtentry *rtable_mpath_match(unsigned int, struct rtentry *, > struct sockaddr *, uint8_t); > -int rtable_mpath_conflict(unsigned int, struct sockaddr *, > - struct sockaddr *, struct sockaddr *, uint8_t, int); > struct rtentry *rtable_mpath_select(struct rtentry *, uint32_t); > void rtable_mpath_reprio(struct rtentry *, uint8_t); > #endif /* _NET_RTABLE_H_ */ > -- :wq Claudio