From 390b3a300d7872cef9588f003b204398be69ce08 Mon Sep 17 00:00:00 2001 From: Ido Schimmel Date: Sun, 21 Sep 2025 18:08:22 +0300 Subject: nexthop: Forbid FDB status change while nexthop is in a group The kernel forbids the creation of non-FDB nexthop groups with FDB nexthops: # ip nexthop add id 1 via 192.0.2.1 fdb # ip nexthop add id 2 group 1 Error: Non FDB nexthop group cannot have fdb nexthops. And vice versa: # ip nexthop add id 3 via 192.0.2.2 dev dummy1 # ip nexthop add id 4 group 3 fdb Error: FDB nexthop group can only have fdb nexthops. However, as long as no routes are pointing to a non-FDB nexthop group, the kernel allows changing the type of a nexthop from FDB to non-FDB and vice versa: # ip nexthop add id 5 via 192.0.2.2 dev dummy1 # ip nexthop add id 6 group 5 # ip nexthop replace id 5 via 192.0.2.2 fdb # echo $? 0 This configuration is invalid and can result in a NPD [1] since FDB nexthops are not associated with a nexthop device: # ip route add 198.51.100.1/32 nhid 6 # ping 198.51.100.1 Fix by preventing nexthop FDB status change while the nexthop is in a group: # ip nexthop add id 7 via 192.0.2.2 dev dummy1 # ip nexthop add id 8 group 7 # ip nexthop replace id 7 via 192.0.2.2 fdb Error: Cannot change nexthop FDB status while in a group. [1] BUG: kernel NULL pointer dereference, address: 00000000000003c0 [...] Oops: Oops: 0000 [#1] SMP CPU: 6 UID: 0 PID: 367 Comm: ping Not tainted 6.17.0-rc6-virtme-gb65678cacc03 #1 PREEMPT(voluntary) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-4.fc41 04/01/2014 RIP: 0010:fib_lookup_good_nhc+0x1e/0x80 [...] Call Trace: fib_table_lookup+0x541/0x650 ip_route_output_key_hash_rcu+0x2ea/0x970 ip_route_output_key_hash+0x55/0x80 __ip4_datagram_connect+0x250/0x330 udp_connect+0x2b/0x60 __sys_connect+0x9c/0xd0 __x64_sys_connect+0x18/0x20 do_syscall_64+0xa4/0x2a0 entry_SYSCALL_64_after_hwframe+0x4b/0x53 Fixes: 38428d68719c ("nexthop: support for fdb ecmp nexthops") Reported-by: syzbot+6596516dd2b635ba2350@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/68c9a4d2.050a0220.3c6139.0e63.GAE@google.com/ Tested-by: syzbot+6596516dd2b635ba2350@syzkaller.appspotmail.com Signed-off-by: Ido Schimmel Reviewed-by: David Ahern Link: https://patch.msgid.link/20250921150824.149157-2-idosch@nvidia.com Signed-off-by: Jakub Kicinski --- net/ipv4/nexthop.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c index 29118c43ebf5..34137768e7f9 100644 --- a/net/ipv4/nexthop.c +++ b/net/ipv4/nexthop.c @@ -2399,6 +2399,13 @@ static int replace_nexthop_single(struct net *net, struct nexthop *old, return -EINVAL; } + if (!list_empty(&old->grp_list) && + rtnl_dereference(new->nh_info)->fdb_nh != + rtnl_dereference(old->nh_info)->fdb_nh) { + NL_SET_ERR_MSG(extack, "Cannot change nexthop FDB status while in a group"); + return -EINVAL; + } + err = call_nexthop_notifiers(net, NEXTHOP_EVENT_REPLACE, new, extack); if (err) return err; -- cgit v1.2.3 From c29913109c70383cdf90b6fc792353e1009f24f5 Mon Sep 17 00:00:00 2001 From: Ido Schimmel Date: Sun, 21 Sep 2025 18:08:23 +0300 Subject: selftests: fib_nexthops: Fix creation of non-FDB nexthops The test creates non-FDB nexthops without a nexthop device which leads to the expected failure, but for the wrong reason: # ./fib_nexthops.sh -t "ipv6_fdb_grp_fcnal ipv4_fdb_grp_fcnal" -v IPv6 fdb groups functional -------------------------- [...] COMMAND: ip -netns me-nRsN3E nexthop add id 63 via 2001:db8:91::4 Error: Device attribute required for non-blackhole and non-fdb nexthops. COMMAND: ip -netns me-nRsN3E nexthop add id 64 via 2001:db8:91::5 Error: Device attribute required for non-blackhole and non-fdb nexthops. COMMAND: ip -netns me-nRsN3E nexthop add id 103 group 63/64 fdb Error: Invalid nexthop id. TEST: Fdb Nexthop group with non-fdb nexthops [ OK ] [...] IPv4 fdb groups functional -------------------------- [...] COMMAND: ip -netns me-nRsN3E nexthop add id 14 via 172.16.1.2 Error: Device attribute required for non-blackhole and non-fdb nexthops. COMMAND: ip -netns me-nRsN3E nexthop add id 15 via 172.16.1.3 Error: Device attribute required for non-blackhole and non-fdb nexthops. COMMAND: ip -netns me-nRsN3E nexthop add id 103 group 14/15 fdb Error: Invalid nexthop id. TEST: Fdb Nexthop group with non-fdb nexthops [ OK ] COMMAND: ip -netns me-nRsN3E nexthop add id 16 via 172.16.1.2 fdb COMMAND: ip -netns me-nRsN3E nexthop add id 17 via 172.16.1.3 fdb COMMAND: ip -netns me-nRsN3E nexthop add id 104 group 14/15 Error: Invalid nexthop id. TEST: Non-Fdb Nexthop group with fdb nexthops [ OK ] [...] COMMAND: ip -netns me-0dlhyd ro add 172.16.0.0/22 nhid 15 Error: Nexthop id does not exist. TEST: Route add with fdb nexthop [ OK ] In addition, as can be seen in the above output, a couple of IPv4 test cases used the non-FDB nexthops (14 and 15) when they intended to use the FDB nexthops (16 and 17). These test cases only passed because failure was expected, but they failed for the wrong reason. Fix the test to create the non-FDB nexthops with a nexthop device and adjust the IPv4 test cases to use the FDB nexthops instead of the non-FDB nexthops. Output after the fix: # ./fib_nexthops.sh -t "ipv6_fdb_grp_fcnal ipv4_fdb_grp_fcnal" -v IPv6 fdb groups functional -------------------------- [...] COMMAND: ip -netns me-lNzfHP nexthop add id 63 via 2001:db8:91::4 dev veth1 COMMAND: ip -netns me-lNzfHP nexthop add id 64 via 2001:db8:91::5 dev veth1 COMMAND: ip -netns me-lNzfHP nexthop add id 103 group 63/64 fdb Error: FDB nexthop group can only have fdb nexthops. TEST: Fdb Nexthop group with non-fdb nexthops [ OK ] [...] IPv4 fdb groups functional -------------------------- [...] COMMAND: ip -netns me-lNzfHP nexthop add id 14 via 172.16.1.2 dev veth1 COMMAND: ip -netns me-lNzfHP nexthop add id 15 via 172.16.1.3 dev veth1 COMMAND: ip -netns me-lNzfHP nexthop add id 103 group 14/15 fdb Error: FDB nexthop group can only have fdb nexthops. TEST: Fdb Nexthop group with non-fdb nexthops [ OK ] COMMAND: ip -netns me-lNzfHP nexthop add id 16 via 172.16.1.2 fdb COMMAND: ip -netns me-lNzfHP nexthop add id 17 via 172.16.1.3 fdb COMMAND: ip -netns me-lNzfHP nexthop add id 104 group 16/17 Error: Non FDB nexthop group cannot have fdb nexthops. TEST: Non-Fdb Nexthop group with fdb nexthops [ OK ] [...] COMMAND: ip -netns me-lNzfHP ro add 172.16.0.0/22 nhid 16 Error: Route cannot point to a fdb nexthop. TEST: Route add with fdb nexthop [ OK ] [...] Tests passed: 30 Tests failed: 0 Tests skipped: 0 Fixes: 0534c5489c11 ("selftests: net: add fdb nexthop tests") Signed-off-by: Ido Schimmel Reviewed-by: David Ahern Link: https://patch.msgid.link/20250921150824.149157-3-idosch@nvidia.com Signed-off-by: Jakub Kicinski --- tools/testing/selftests/net/fib_nexthops.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/testing/selftests/net/fib_nexthops.sh b/tools/testing/selftests/net/fib_nexthops.sh index b39f748c2572..2ac394c99d01 100755 --- a/tools/testing/selftests/net/fib_nexthops.sh +++ b/tools/testing/selftests/net/fib_nexthops.sh @@ -467,8 +467,8 @@ ipv6_fdb_grp_fcnal() log_test $? 0 "Get Fdb nexthop group by id" # fdb nexthop group can only contain fdb nexthops - run_cmd "$IP nexthop add id 63 via 2001:db8:91::4" - run_cmd "$IP nexthop add id 64 via 2001:db8:91::5" + run_cmd "$IP nexthop add id 63 via 2001:db8:91::4 dev veth1" + run_cmd "$IP nexthop add id 64 via 2001:db8:91::5 dev veth1" run_cmd "$IP nexthop add id 103 group 63/64 fdb" log_test $? 2 "Fdb Nexthop group with non-fdb nexthops" @@ -547,15 +547,15 @@ ipv4_fdb_grp_fcnal() log_test $? 0 "Get Fdb nexthop group by id" # fdb nexthop group can only contain fdb nexthops - run_cmd "$IP nexthop add id 14 via 172.16.1.2" - run_cmd "$IP nexthop add id 15 via 172.16.1.3" + run_cmd "$IP nexthop add id 14 via 172.16.1.2 dev veth1" + run_cmd "$IP nexthop add id 15 via 172.16.1.3 dev veth1" run_cmd "$IP nexthop add id 103 group 14/15 fdb" log_test $? 2 "Fdb Nexthop group with non-fdb nexthops" # Non fdb nexthop group can not contain fdb nexthops run_cmd "$IP nexthop add id 16 via 172.16.1.2 fdb" run_cmd "$IP nexthop add id 17 via 172.16.1.3 fdb" - run_cmd "$IP nexthop add id 104 group 14/15" + run_cmd "$IP nexthop add id 104 group 16/17" log_test $? 2 "Non-Fdb Nexthop group with fdb nexthops" # fdb nexthop cannot have blackhole @@ -582,7 +582,7 @@ ipv4_fdb_grp_fcnal() run_cmd "$BRIDGE fdb add 02:02:00:00:00:14 dev vx10 nhid 12 self" log_test $? 255 "Fdb mac add with nexthop" - run_cmd "$IP ro add 172.16.0.0/22 nhid 15" + run_cmd "$IP ro add 172.16.0.0/22 nhid 16" log_test $? 2 "Route add with fdb nexthop" run_cmd "$IP ro add 172.16.0.0/22 nhid 103" -- cgit v1.2.3 From 00af023d90f9087ed5a371302ab442ed5736c3b7 Mon Sep 17 00:00:00 2001 From: Ido Schimmel Date: Sun, 21 Sep 2025 18:08:24 +0300 Subject: selftests: fib_nexthops: Add test cases for FDB status change Add the following test cases for both IPv4 and IPv6: * Can change from FDB nexthop to non-FDB nexthop and vice versa. * Can change FDB nexthop address while in a group. * Cannot change from FDB nexthop to non-FDB nexthop and vice versa while in a group. Output without "nexthop: Forbid FDB status change while nexthop is in a group": # ./fib_nexthops.sh -t "ipv6_fdb_grp_fcnal ipv4_fdb_grp_fcnal" IPv6 fdb groups functional -------------------------- [...] TEST: Replace FDB nexthop to non-FDB nexthop [ OK ] TEST: Replace non-FDB nexthop to FDB nexthop [ OK ] TEST: Replace FDB nexthop address while in a group [ OK ] TEST: Replace FDB nexthop to non-FDB nexthop while in a group [FAIL] TEST: Replace non-FDB nexthop to FDB nexthop while in a group [FAIL] [...] IPv4 fdb groups functional -------------------------- [...] TEST: Replace FDB nexthop to non-FDB nexthop [ OK ] TEST: Replace non-FDB nexthop to FDB nexthop [ OK ] TEST: Replace FDB nexthop address while in a group [ OK ] TEST: Replace FDB nexthop to non-FDB nexthop while in a group [FAIL] TEST: Replace non-FDB nexthop to FDB nexthop while in a group [FAIL] [...] Tests passed: 36 Tests failed: 4 Tests skipped: 0 Output with "nexthop: Forbid FDB status change while nexthop is in a group": # ./fib_nexthops.sh -t "ipv6_fdb_grp_fcnal ipv4_fdb_grp_fcnal" IPv6 fdb groups functional -------------------------- [...] TEST: Replace FDB nexthop to non-FDB nexthop [ OK ] TEST: Replace non-FDB nexthop to FDB nexthop [ OK ] TEST: Replace FDB nexthop address while in a group [ OK ] TEST: Replace FDB nexthop to non-FDB nexthop while in a group [ OK ] TEST: Replace non-FDB nexthop to FDB nexthop while in a group [ OK ] [...] IPv4 fdb groups functional -------------------------- [...] TEST: Replace FDB nexthop to non-FDB nexthop [ OK ] TEST: Replace non-FDB nexthop to FDB nexthop [ OK ] TEST: Replace FDB nexthop address while in a group [ OK ] TEST: Replace FDB nexthop to non-FDB nexthop while in a group [ OK ] TEST: Replace non-FDB nexthop to FDB nexthop while in a group [ OK ] [...] Tests passed: 40 Tests failed: 0 Tests skipped: 0 Signed-off-by: Ido Schimmel Reviewed-by: David Ahern Link: https://patch.msgid.link/20250921150824.149157-4-idosch@nvidia.com Signed-off-by: Jakub Kicinski --- tools/testing/selftests/net/fib_nexthops.sh | 40 +++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tools/testing/selftests/net/fib_nexthops.sh b/tools/testing/selftests/net/fib_nexthops.sh index 2ac394c99d01..2b0a90581e2f 100755 --- a/tools/testing/selftests/net/fib_nexthops.sh +++ b/tools/testing/selftests/net/fib_nexthops.sh @@ -494,6 +494,26 @@ ipv6_fdb_grp_fcnal() run_cmd "$IP nexthop add id 69 encap mpls 101 via 2001:db8:91::8 dev veth1 fdb" log_test $? 2 "Fdb Nexthop with encap" + # Replace FDB nexthop to non-FDB and vice versa + run_cmd "$IP nexthop add id 70 via 2001:db8:91::2 fdb" + run_cmd "$IP nexthop replace id 70 via 2001:db8:91::2 dev veth1" + log_test $? 0 "Replace FDB nexthop to non-FDB nexthop" + run_cmd "$IP nexthop replace id 70 via 2001:db8:91::2 fdb" + log_test $? 0 "Replace non-FDB nexthop to FDB nexthop" + + # Replace FDB nexthop address while in a group + run_cmd "$IP nexthop add id 71 group 70 fdb" + run_cmd "$IP nexthop replace id 70 via 2001:db8:91::3 fdb" + log_test $? 0 "Replace FDB nexthop address while in a group" + + # Cannot replace FDB nexthop to non-FDB and vice versa while in a group + run_cmd "$IP nexthop replace id 70 via 2001:db8:91::2 dev veth1" + log_test $? 2 "Replace FDB nexthop to non-FDB nexthop while in a group" + run_cmd "$IP nexthop add id 72 via 2001:db8:91::2 dev veth1" + run_cmd "$IP nexthop add id 73 group 72" + run_cmd "$IP nexthop replace id 72 via 2001:db8:91::2 fdb" + log_test $? 2 "Replace non-FDB nexthop to FDB nexthop while in a group" + run_cmd "$IP link add name vx10 type vxlan id 1010 local 2001:db8:91::9 remote 2001:db8:91::10 dstport 4789 nolearning noudpcsum tos inherit ttl 100" run_cmd "$BRIDGE fdb add 02:02:00:00:00:13 dev vx10 nhid 102 self" log_test $? 0 "Fdb mac add with nexthop group" @@ -574,6 +594,26 @@ ipv4_fdb_grp_fcnal() run_cmd "$IP nexthop add id 17 encap mpls 101 via 172.16.1.2 dev veth1 fdb" log_test $? 2 "Fdb Nexthop with encap" + # Replace FDB nexthop to non-FDB and vice versa + run_cmd "$IP nexthop add id 18 via 172.16.1.2 fdb" + run_cmd "$IP nexthop replace id 18 via 172.16.1.2 dev veth1" + log_test $? 0 "Replace FDB nexthop to non-FDB nexthop" + run_cmd "$IP nexthop replace id 18 via 172.16.1.2 fdb" + log_test $? 0 "Replace non-FDB nexthop to FDB nexthop" + + # Replace FDB nexthop address while in a group + run_cmd "$IP nexthop add id 19 group 18 fdb" + run_cmd "$IP nexthop replace id 18 via 172.16.1.3 fdb" + log_test $? 0 "Replace FDB nexthop address while in a group" + + # Cannot replace FDB nexthop to non-FDB and vice versa while in a group + run_cmd "$IP nexthop replace id 18 via 172.16.1.2 dev veth1" + log_test $? 2 "Replace FDB nexthop to non-FDB nexthop while in a group" + run_cmd "$IP nexthop add id 20 via 172.16.1.2 dev veth1" + run_cmd "$IP nexthop add id 21 group 20" + run_cmd "$IP nexthop replace id 20 via 172.16.1.2 fdb" + log_test $? 2 "Replace non-FDB nexthop to FDB nexthop while in a group" + run_cmd "$IP link add name vx10 type vxlan id 1010 local 10.0.0.1 remote 10.0.0.2 dstport 4789 nolearning noudpcsum tos inherit ttl 100" run_cmd "$BRIDGE fdb add 02:02:00:00:00:13 dev vx10 nhid 102 self" log_test $? 0 "Fdb mac add with nexthop group" -- cgit v1.2.3