Skip to content

Commit 3d709f6

Browse files
idoschdavem330
authored andcommitted
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 <[email protected]> Acked-by: David Ahern <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 7696c06 commit 3d709f6

File tree

1 file changed

+13
-23
lines changed

1 file changed

+13
-23
lines changed

net/ipv6/route.c

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -455,36 +455,26 @@ static struct rt6_info *rt6_multipath_select(struct rt6_info *match,
455455
int strict)
456456
{
457457
struct rt6_info *sibling, *next_sibling;
458-
int route_choosen;
459458

460459
/* We might have already computed the hash for ICMPv6 errors. In such
461460
* case it will always be non-zero. Otherwise now is the time to do it.
462461
*/
463462
if (!fl6->mp_hash)
464463
fl6->mp_hash = rt6_multipath_hash(fl6, NULL);
465464

466-
route_choosen = fl6->mp_hash % (match->rt6i_nsiblings + 1);
467-
/* Don't change the route, if route_choosen == 0
468-
* (siblings does not include ourself)
469-
*/
470-
if (route_choosen)
471-
list_for_each_entry_safe(sibling, next_sibling,
472-
&match->rt6i_siblings, rt6i_siblings) {
473-
route_choosen--;
474-
if (route_choosen == 0) {
475-
struct inet6_dev *idev = sibling->rt6i_idev;
476-
477-
if (sibling->rt6i_nh_flags & RTNH_F_DEAD)
478-
break;
479-
if (sibling->rt6i_nh_flags & RTNH_F_LINKDOWN &&
480-
idev->cnf.ignore_routes_with_linkdown)
481-
break;
482-
if (rt6_score_route(sibling, oif, strict) < 0)
483-
break;
484-
match = sibling;
485-
break;
486-
}
487-
}
465+
if (fl6->mp_hash <= atomic_read(&match->rt6i_nh_upper_bound))
466+
return match;
467+
468+
list_for_each_entry_safe(sibling, next_sibling, &match->rt6i_siblings,
469+
rt6i_siblings) {
470+
if (fl6->mp_hash > atomic_read(&sibling->rt6i_nh_upper_bound))
471+
continue;
472+
if (rt6_score_route(sibling, oif, strict) < 0)
473+
break;
474+
match = sibling;
475+
break;
476+
}
477+
488478
return match;
489479
}
490480

0 commit comments

Comments
 (0)