mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 05:02:12 +00:00
ipv6: Use hash-threshold instead of modulo-N
Now that each nexthop stores its region boundary in the multipath hash function's output space, we can use hash-threshold instead of modulo-N in multipath selection. This reduces the number of checks we need to perform during lookup, as dead and linkdown nexthops are assigned a negative region boundary. In addition, in contrast to modulo-N, only flows near region boundaries are affected when a nexthop is added or removed. Signed-off-by: Ido Schimmel <idosch@mellanox.com> Acked-by: David Ahern <dsahern@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
7696c06a18
commit
3d709f69a3
@ -455,7 +455,6 @@ static struct rt6_info *rt6_multipath_select(struct rt6_info *match,
|
||||
int strict)
|
||||
{
|
||||
struct rt6_info *sibling, *next_sibling;
|
||||
int route_choosen;
|
||||
|
||||
/* We might have already computed the hash for ICMPv6 errors. In such
|
||||
* case it will always be non-zero. Otherwise now is the time to do it.
|
||||
@ -463,28 +462,19 @@ static struct rt6_info *rt6_multipath_select(struct rt6_info *match,
|
||||
if (!fl6->mp_hash)
|
||||
fl6->mp_hash = rt6_multipath_hash(fl6, NULL);
|
||||
|
||||
route_choosen = fl6->mp_hash % (match->rt6i_nsiblings + 1);
|
||||
/* Don't change the route, if route_choosen == 0
|
||||
* (siblings does not include ourself)
|
||||
*/
|
||||
if (route_choosen)
|
||||
list_for_each_entry_safe(sibling, next_sibling,
|
||||
&match->rt6i_siblings, rt6i_siblings) {
|
||||
route_choosen--;
|
||||
if (route_choosen == 0) {
|
||||
struct inet6_dev *idev = sibling->rt6i_idev;
|
||||
if (fl6->mp_hash <= atomic_read(&match->rt6i_nh_upper_bound))
|
||||
return match;
|
||||
|
||||
list_for_each_entry_safe(sibling, next_sibling, &match->rt6i_siblings,
|
||||
rt6i_siblings) {
|
||||
if (fl6->mp_hash > atomic_read(&sibling->rt6i_nh_upper_bound))
|
||||
continue;
|
||||
if (rt6_score_route(sibling, oif, strict) < 0)
|
||||
break;
|
||||
match = sibling;
|
||||
break;
|
||||
}
|
||||
|
||||
if (sibling->rt6i_nh_flags & RTNH_F_DEAD)
|
||||
break;
|
||||
if (sibling->rt6i_nh_flags & RTNH_F_LINKDOWN &&
|
||||
idev->cnf.ignore_routes_with_linkdown)
|
||||
break;
|
||||
if (rt6_score_route(sibling, oif, strict) < 0)
|
||||
break;
|
||||
match = sibling;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return match;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user