mirror of
https://github.com/torvalds/linux.git
synced 2026-05-25 15:41:52 +02:00
Merge branch 'ipv6-multipath-routing-fixes'
Ido Schimmel says: ==================== ipv6: Multipath routing fixes This patchset contains two fixes for IPv6 multipath routing. See the commit messages for more details. ==================== Link: https://patch.msgid.link/20250402114224.293392-1-idosch@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
613f727c5b
|
|
@ -412,12 +412,37 @@ static bool rt6_check_expired(const struct rt6_info *rt)
|
|||
return false;
|
||||
}
|
||||
|
||||
static struct fib6_info *
|
||||
rt6_multipath_first_sibling_rcu(const struct fib6_info *rt)
|
||||
{
|
||||
struct fib6_info *iter;
|
||||
struct fib6_node *fn;
|
||||
|
||||
fn = rcu_dereference(rt->fib6_node);
|
||||
if (!fn)
|
||||
goto out;
|
||||
iter = rcu_dereference(fn->leaf);
|
||||
if (!iter)
|
||||
goto out;
|
||||
|
||||
while (iter) {
|
||||
if (iter->fib6_metric == rt->fib6_metric &&
|
||||
rt6_qualify_for_ecmp(iter))
|
||||
return iter;
|
||||
iter = rcu_dereference(iter->fib6_next);
|
||||
}
|
||||
|
||||
out:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void fib6_select_path(const struct net *net, struct fib6_result *res,
|
||||
struct flowi6 *fl6, int oif, bool have_oif_match,
|
||||
const struct sk_buff *skb, int strict)
|
||||
{
|
||||
struct fib6_info *match = res->f6i;
|
||||
struct fib6_info *first, *match = res->f6i;
|
||||
struct fib6_info *sibling;
|
||||
int hash;
|
||||
|
||||
if (!match->nh && (!match->fib6_nsiblings || have_oif_match))
|
||||
goto out;
|
||||
|
|
@ -440,16 +465,25 @@ void fib6_select_path(const struct net *net, struct fib6_result *res,
|
|||
return;
|
||||
}
|
||||
|
||||
if (fl6->mp_hash <= atomic_read(&match->fib6_nh->fib_nh_upper_bound))
|
||||
first = rt6_multipath_first_sibling_rcu(match);
|
||||
if (!first)
|
||||
goto out;
|
||||
|
||||
list_for_each_entry_rcu(sibling, &match->fib6_siblings,
|
||||
hash = fl6->mp_hash;
|
||||
if (hash <= atomic_read(&first->fib6_nh->fib_nh_upper_bound) &&
|
||||
rt6_score_route(first->fib6_nh, first->fib6_flags, oif,
|
||||
strict) >= 0) {
|
||||
match = first;
|
||||
goto out;
|
||||
}
|
||||
|
||||
list_for_each_entry_rcu(sibling, &first->fib6_siblings,
|
||||
fib6_siblings) {
|
||||
const struct fib6_nh *nh = sibling->fib6_nh;
|
||||
int nh_upper_bound;
|
||||
|
||||
nh_upper_bound = atomic_read(&nh->fib_nh_upper_bound);
|
||||
if (fl6->mp_hash > nh_upper_bound)
|
||||
if (hash > nh_upper_bound)
|
||||
continue;
|
||||
if (rt6_score_route(nh, sibling->fib6_flags, oif, strict) < 0)
|
||||
break;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user