Skip to content

Commit 17a7eac

Browse files
author
Guillaume Nault
committed
vxlan: Add RCU read-side critical sections in the Tx path
JIRA: https://issues.redhat.com/browse/RHEL-115639 Upstream Status: linux.git commit 804b09b Author: Ido Schimmel <idosch@nvidia.com> Date: Tue Apr 15 15:11:29 2025 +0300 vxlan: Add RCU read-side critical sections in the Tx path The Tx path does not run from an RCU read-side critical section which makes the current lockless accesses to FDB entries invalid. As far as I am aware, this has not been a problem in practice, but traces will be generated once we transition the FDB lookup to rhashtable_lookup(). Add rcu_read_{lock,unlock}() around the handling of FDB entries in the Tx path. Remove the RCU read-side critical section from vxlan_xmit_nh() as now the function is always called from an RCU read-side critical section. Reviewed-by: Petr Machata <petrm@nvidia.com> Signed-off-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20250415121143.345227-2-idosch@nvidia.com Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Guillaume Nault <gnault@redhat.com>
1 parent b19f127 commit 17a7eac

File tree

1 file changed

+8
-6
lines changed

1 file changed

+8
-6
lines changed

drivers/net/vxlan/vxlan_core.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1916,12 +1916,15 @@ static int arp_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni)
19161916
goto out;
19171917
}
19181918

1919+
rcu_read_lock();
19191920
f = vxlan_find_mac(vxlan, n->ha, vni);
19201921
if (f && vxlan_addr_any(&(first_remote_rcu(f)->remote_ip))) {
19211922
/* bridge-local neighbor */
19221923
neigh_release(n);
1924+
rcu_read_unlock();
19231925
goto out;
19241926
}
1927+
rcu_read_unlock();
19251928

19261929
reply = arp_create(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip, sha,
19271930
n->ha, sha);
@@ -2638,14 +2641,10 @@ static void vxlan_xmit_nh(struct sk_buff *skb, struct net_device *dev,
26382641
memset(&nh_rdst, 0, sizeof(struct vxlan_rdst));
26392642
hash = skb_get_hash(skb);
26402643

2641-
rcu_read_lock();
26422644
nh = rcu_dereference(f->nh);
2643-
if (!nh) {
2644-
rcu_read_unlock();
2645+
if (!nh)
26452646
goto drop;
2646-
}
26472647
do_xmit = vxlan_fdb_nh_path_select(nh, hash, &nh_rdst);
2648-
rcu_read_unlock();
26492648

26502649
if (likely(do_xmit))
26512650
vxlan_xmit_one(skb, dev, vni, &nh_rdst, did_rsc);
@@ -2772,6 +2771,7 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
27722771
}
27732772

27742773
eth = eth_hdr(skb);
2774+
rcu_read_lock();
27752775
f = vxlan_find_mac(vxlan, eth->h_dest, vni);
27762776
did_rsc = false;
27772777

@@ -2794,7 +2794,7 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
27942794
vxlan_vnifilter_count(vxlan, vni, NULL,
27952795
VXLAN_VNI_STATS_TX_DROPS, 0);
27962796
kfree_skb_reason(skb, SKB_DROP_REASON_NO_TX_TARGET);
2797-
return NETDEV_TX_OK;
2797+
goto out;
27982798
}
27992799
}
28002800

@@ -2819,6 +2819,8 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
28192819
kfree_skb_reason(skb, SKB_DROP_REASON_NO_TX_TARGET);
28202820
}
28212821

2822+
out:
2823+
rcu_read_unlock();
28222824
return NETDEV_TX_OK;
28232825
}
28242826

0 commit comments

Comments
 (0)