libnl3/backport-fix-IPv6-ecmp-route-deleted-nexthop-matching.patch

67 lines
2.5 KiB
Diff
Raw Permalink Normal View History

From 2301992be667fa51084b40ac6ad4a4155a09aeb1 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jonas.gorski@bisdn.de>
Date: Tue, 30 Apr 2024 14:05:33 +0200
Subject: [PATCH] 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
Conflict:NA
Reference:https://github.com/thom311/libnl/commit/2301992be667fa51084b40ac6ad4a4155a09aeb1
---
lib/route/route_obj.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/lib/route/route_obj.c b/lib/route/route_obj.c
index 9441b77..0ae029d 100644
--- a/lib/route/route_obj.c
+++ b/lib/route/route_obj.c
@@ -547,7 +547,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);
--
2.33.0