diff options
author | Jonas Gorski <jonas.gorski@bisdn.de> | 2024-04-30 12:05:33 (GMT) |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2024-05-07 07:33:59 (GMT) |
commit | 2301992be667fa51084b40ac6ad4a4155a09aeb1 (patch) | |
tree | 772c4a12f7e3269e2ce81f88c3618687f0998214 | |
parent | 72e4d73fe9f9cd9d68a63e0ad44f22390d3c37f1 (diff) | |
download | libnl-2301992be667fa51084b40ac6ad4a4155a09aeb1.zip libnl-2301992be667fa51084b40ac6ad4a4155a09aeb1.tar.gz libnl-2301992be667fa51084b40ac6ad4a4155a09aeb1.tar.bz2 |
route: fix IPv6 ecmp route deleted nexthop matching
When the kernel sends a ECMP route update with just the deleted nexthop,
the nexthop will have no associated weight, and its flags may indicate
that it is dead:
route_update: RTM_DELROUTE
new route:
inet6 default table main type unicast <DEAD,>
scope global priority 0x400 protocol 0x9
nexthop via fe80::b226:28ff:fe62:8841 dev port4 <dead,>
old route:
inet6 default table main type unicast
scope global priority 0x400 protocol 0x9
nexthop via fe80::b226:28ff:fe62:8841 dev port4 weight 0 <>
nexthop via fe80::fa8e:a1ff:fee0:8344 dev port49 weight 0 <>
nexthop via fe80::b226:28ff:fe62:d400 dev port3 weight 0 <>
nexthop via fe80::fa8e:a1ff:fee0:8349 dev port54 weight 0 <>
Since we are comparing the nexthops strictly with all attributes, we can
never match the deleted nexthop. This causes libnl to fail to remove the
deleted nexthop from the route, and consequently send out a nop-update
and a desync of the route in the cache and in the kernel.
Fix this by ignoring NH_ATTR_FLAGS (0x1) and NH_ATTR_WEIGHT (0x2) when
comparing nexthops to properly match the deleted one.
Fixes: 29b71371e764 ("route cache: Fix handling of ipv6 multipath routes")
Signed-off-by: Jonas Gorski <jonas.gorski@bisdn.de>
https://github.com/thom311/libnl/pull/382
-rw-r--r-- | lib/route/route_obj.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/lib/route/route_obj.c b/lib/route/route_obj.c index 5077593..aba1a1b 100644 --- a/lib/route/route_obj.c +++ b/lib/route/route_obj.c @@ -574,7 +574,15 @@ static int route_update(struct nl_object *old_obj, struct nl_object *new_obj) */ nl_list_for_each_entry(old_nh, &old_route->rt_nexthops, rtnh_list) { - if (!rtnl_route_nh_compare(old_nh, new_nh, ~0, 0)) { + /* + * Since the new route has only one nexthop, it's not + * an ECMP route and the nexthop won't have a weight. + * Similarily, the nexthop might have been marked as + * DEAD in its flags if it was deleted. + * Therefore ignore NH_ATTR_FLAGS (= 0x1) and + * NH_ATTR_WEIGHT (= 0x2) while comparing nexthops. + */ + if (!rtnl_route_nh_compare(old_nh, new_nh, ~0x3, 0)) { rtnl_route_remove_nexthop(old_route, old_nh); |