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.
This commit is contained in:
parent
e5f3746abd
commit
59747033cd
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=293657
@ -197,14 +197,49 @@ rt_mpath_conflict(struct radix_node_head *rnh, struct rtentry *rt,
|
||||
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, uint32_t hash, u_int fibnum)
|
||||
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);
|
||||
|
||||
|
@ -52,6 +52,7 @@ int rt_mpath_conflict(struct radix_node_head *, struct rtentry *,
|
||||
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 *);
|
||||
|
@ -200,6 +200,13 @@ fib4_lookup_nh_ext(uint32_t fibnum, struct in_addr dst, uint32_t flags,
|
||||
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);
|
||||
|
@ -241,6 +241,13 @@ fib6_lookup_nh_ext(uint32_t fibnum, const struct in6_addr *dst,uint32_t scopeid,
|
||||
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,
|
||||
|
Loading…
Reference in New Issue
Block a user