67 lines
2.5 KiB
Diff
67 lines
2.5 KiB
Diff
|
|
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
|
||
|
|
|