Author: melifaro Date: Mon Jan 11 08:45:28 2016 New Revision: 293657 URL: https://svnweb.freebsd.org/changeset/base/293657
Log: Bring RADIX_MPATH support to new routing KPI to ease migration. Move actual rte selection process from rtalloc_mpath_fib() to the rt_path_selectrte() function. Add public rt_mpath_select() to use in fibX_lookup_ functions. Modified: head/sys/net/radix_mpath.c head/sys/net/radix_mpath.h head/sys/netinet/in_fib.c head/sys/netinet6/in6_fib.c Modified: head/sys/net/radix_mpath.c ============================================================================== --- head/sys/net/radix_mpath.c Mon Jan 11 08:00:13 2016 (r293656) +++ head/sys/net/radix_mpath.c Mon Jan 11 08:45:28 2016 (r293657) @@ -197,14 +197,49 @@ rt_mpath_conflict(struct radix_node_head return (0); } -void -rtalloc_mpath_fib(struct route *ro, uint32_t hash, u_int fibnum) +static struct rtentry * +rt_mpath_selectrte(struct rtentry *rte, uint32_t hash) { struct radix_node *rn0, *rn; u_int32_t n; struct rtentry *rt; int64_t weight; + /* beyond here, we use rn as the master copy */ + rn0 = rn = (struct radix_node *)rte; + n = rn_mpath_count(rn0); + + /* gw selection by Modulo-N Hash (RFC2991) XXX need improvement? */ + hash += hashjitter; + hash %= n; + for (weight = abs((int32_t)hash), rt = rte; + weight >= rt->rt_weight && rn; + weight -= rt->rt_weight) { + + /* stay within the multipath routes */ + if (rn->rn_dupedkey && rn->rn_mask != rn->rn_dupedkey->rn_mask) + break; + rn = rn->rn_dupedkey; + rt = (struct rtentry *)rn; + } + + return (rt); +} + +struct rtentry * +rt_mpath_select(struct rtentry *rte, uint32_t hash) +{ + if (rn_mpath_next((struct radix_node *)rte) == NULL) + return (rte); + + return (rt_mpath_selectrte(rte, hash)); +} + +void +rtalloc_mpath_fib(struct route *ro, uint32_t hash, u_int fibnum) +{ + struct rtentry *rt; + /* * XXX we don't attempt to lookup cached route again; what should * be done for sendto(3) case? @@ -222,34 +257,18 @@ rtalloc_mpath_fib(struct route *ro, uint return; } - /* beyond here, we use rn as the master copy */ - rn0 = rn = (struct radix_node *)ro->ro_rt; - n = rn_mpath_count(rn0); - - /* gw selection by Modulo-N Hash (RFC2991) XXX need improvement? */ - hash += hashjitter; - hash %= n; - for (weight = abs((int32_t)hash), rt = ro->ro_rt; - weight >= rt->rt_weight && rn; - weight -= rt->rt_weight) { - - /* stay within the multipath routes */ - if (rn->rn_dupedkey && rn->rn_mask != rn->rn_dupedkey->rn_mask) - break; - rn = rn->rn_dupedkey; - rt = (struct rtentry *)rn; - } + rt = rt_mpath_selectrte(ro->ro_rt, hash); /* XXX try filling rt_gwroute and avoid unreachable gw */ /* gw selection has failed - there must be only zero weight routes */ - if (!rn) { + if (!rt) { RT_UNLOCK(ro->ro_rt); ro->ro_rt = NULL; return; } if (ro->ro_rt != rt) { RTFREE_LOCKED(ro->ro_rt); - ro->ro_rt = (struct rtentry *)rn; + ro->ro_rt = rt; RT_LOCK(ro->ro_rt); RT_ADDREF(ro->ro_rt); Modified: head/sys/net/radix_mpath.h ============================================================================== --- head/sys/net/radix_mpath.h Mon Jan 11 08:00:13 2016 (r293656) +++ head/sys/net/radix_mpath.h Mon Jan 11 08:45:28 2016 (r293657) @@ -52,6 +52,7 @@ int rt_mpath_conflict(struct radix_node_ struct sockaddr *); void rtalloc_mpath_fib(struct route *, u_int32_t, u_int); #define rtalloc_mpath(_route, _hash) rtalloc_mpath_fib((_route), (_hash), 0) +struct rtentry *rt_mpath_select(struct rtentry *, uint32_t); struct radix_node *rn_mpath_lookup(void *, void *, struct radix_node_head *); int rt_mpath_deldup(struct rtentry *, struct rtentry *); Modified: head/sys/netinet/in_fib.c ============================================================================== --- head/sys/netinet/in_fib.c Mon Jan 11 08:00:13 2016 (r293656) +++ head/sys/netinet/in_fib.c Mon Jan 11 08:45:28 2016 (r293657) @@ -200,6 +200,13 @@ fib4_lookup_nh_ext(uint32_t fibnum, stru rn = rh->rnh_matchaddr((void *)&sin, rh); if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) { rte = RNTORT(rn); +#ifdef RADIX_MPATH + rte = rt_mpath_select(rte, flowid); + if (rte == NULL) { + RADIX_NODE_HEAD_RUNLOCK(rh); + return (ENOENT); + } +#endif /* Ensure route & ifp is UP */ if (RT_LINK_IS_UP(rte->rt_ifp)) { fib4_rte_to_nh_extended(rte, dst, flags, pnh4); Modified: head/sys/netinet6/in6_fib.c ============================================================================== --- head/sys/netinet6/in6_fib.c Mon Jan 11 08:00:13 2016 (r293656) +++ head/sys/netinet6/in6_fib.c Mon Jan 11 08:45:28 2016 (r293657) @@ -241,6 +241,13 @@ fib6_lookup_nh_ext(uint32_t fibnum, cons rn = rh->rnh_matchaddr((void *)&sin6, rh); if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) { rte = RNTORT(rn); +#ifdef RADIX_MPATH + rte = rt_mpath_select(rte, flowid); + if (rte == NULL) { + RADIX_NODE_HEAD_RUNLOCK(rh); + return (ENOENT); + } +#endif /* Ensure route & ifp is UP */ if (RT_LINK_IS_UP(rte->rt_ifp)) { fib6_rte_to_nh_extended(rte, &sin6.sin6_addr, flags, _______________________________________________ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"