Skip to content

Commit f1b60ff

Browse files
author
Guillaume Nault
committed
vxlan: Fix NPD when refreshing an FDB entry with a nexthop object
JIRA: https://issues.redhat.com/browse/RHEL-115591 Upstream Status: linux.git Conflicts: (context) Missing upstream commit c4f2082 ("vxlan: Always refresh FDB 'updated' time when learning is enabled"): Centos Stream 10 doesn't refresh the FDB entry unconditionally in vxlan_snoop(). commit 6ead381 Author: Ido Schimmel <[email protected]> Date: Mon Sep 1 09:50:33 2025 +0300 vxlan: Fix NPD when refreshing an FDB entry with a nexthop object VXLAN FDB entries can point to either a remote destination or an FDB nexthop group. The latter is usually used in EVPN deployments where learning is disabled. However, when learning is enabled, an incoming packet might try to refresh an FDB entry that points to an FDB nexthop group and therefore does not have a remote. Such packets should be dropped, but they are only dropped after dereferencing the non-existent remote, resulting in a NPD [1] which can be reproduced using [2]. Fix by dropping such packets earlier. Remove the misleading comment from first_remote_rcu(). [1] BUG: kernel NULL pointer dereference, address: 0000000000000000 [...] CPU: 13 UID: 0 PID: 361 Comm: mausezahn Not tainted 6.17.0-rc1-virtme-g9f6b606b6b37 #1 PREEMPT(voluntary) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-4.fc41 04/01/2014 RIP: 0010:vxlan_snoop+0x98/0x1e0 [...] Call Trace: <TASK> vxlan_encap_bypass+0x209/0x240 encap_bypass_if_local+0xb1/0x100 vxlan_xmit_one+0x1375/0x17e0 vxlan_xmit+0x6b4/0x15f0 dev_hard_start_xmit+0x5d/0x1c0 __dev_queue_xmit+0x246/0xfd0 packet_sendmsg+0x113a/0x1850 __sock_sendmsg+0x38/0x70 __sys_sendto+0x126/0x180 __x64_sys_sendto+0x24/0x30 do_syscall_64+0xa4/0x260 entry_SYSCALL_64_after_hwframe+0x4b/0x53 [2] #!/bin/bash ip address add 192.0.2.1/32 dev lo ip address add 192.0.2.2/32 dev lo ip nexthop add id 1 via 192.0.2.3 fdb ip nexthop add id 10 group 1 fdb ip link add name vx0 up type vxlan id 10010 local 192.0.2.1 dstport 12345 localbypass ip link add name vx1 up type vxlan id 10020 local 192.0.2.2 dstport 54321 learning bridge fdb add 00:11:22:33:44:55 dev vx0 self static dst 192.0.2.2 port 54321 vni 10020 bridge fdb add 00:aa:bb:cc:dd:ee dev vx1 self static nhid 10 mausezahn vx0 -a 00:aa:bb:cc:dd:ee -b 00:11:22:33:44:55 -c 1 -q Fixes: 1274e1c ("vxlan: ecmp support for mac fdb entries") Reported-by: Marlin Cremers <[email protected]> Reviewed-by: Petr Machata <[email protected]> Signed-off-by: Ido Schimmel <[email protected]> Reviewed-by: Nikolay Aleksandrov <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]> Signed-off-by: Guillaume Nault <[email protected]>
1 parent 5633667 commit f1b60ff

File tree

2 files changed

+5
-7
lines changed

2 files changed

+5
-7
lines changed

drivers/net/vxlan/vxlan_core.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1466,6 +1466,10 @@ static enum skb_drop_reason vxlan_snoop(struct net_device *dev,
14661466
if (likely(f)) {
14671467
struct vxlan_rdst *rdst = first_remote_rcu(f);
14681468

1469+
/* Don't override an fdb with nexthop with a learnt entry */
1470+
if (rcu_access_pointer(f->nh))
1471+
return SKB_DROP_REASON_VXLAN_ENTRY_EXISTS;
1472+
14691473
if (likely(vxlan_addr_equal(&rdst->remote_ip, src_ip) &&
14701474
rdst->remote_ifindex == ifindex))
14711475
return SKB_NOT_DROPPED_YET;
@@ -1474,10 +1478,6 @@ static enum skb_drop_reason vxlan_snoop(struct net_device *dev,
14741478
if (f->state & (NUD_PERMANENT | NUD_NOARP))
14751479
return SKB_DROP_REASON_VXLAN_ENTRY_EXISTS;
14761480

1477-
/* Don't override an fdb with nexthop with a learnt entry */
1478-
if (rcu_access_pointer(f->nh))
1479-
return SKB_DROP_REASON_VXLAN_ENTRY_EXISTS;
1480-
14811481
if (net_ratelimit())
14821482
netdev_info(dev,
14831483
"%pM migrated from %pIS to %pIS\n",

drivers/net/vxlan/vxlan_private.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,7 @@ static inline struct hlist_head *vs_head(struct net *net, __be16 port)
5656
return &vn->sock_list[hash_32(ntohs(port), PORT_HASH_BITS)];
5757
}
5858

59-
/* First remote destination for a forwarding entry.
60-
* Guaranteed to be non-NULL because remotes are never deleted.
61-
*/
59+
/* First remote destination for a forwarding entry. */
6260
static inline struct vxlan_rdst *first_remote_rcu(struct vxlan_fdb *fdb)
6361
{
6462
if (rcu_access_pointer(fdb->nh))

0 commit comments

Comments
 (0)