mirror of
https://github.com/torvalds/linux.git
synced 2026-05-24 23:22:31 +02:00
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>
This commit is contained in:
parent
07e32237ed
commit
804b09be09
|
|
@ -1916,12 +1916,15 @@ static int arp_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni)
|
|||
goto out;
|
||||
}
|
||||
|
||||
rcu_read_lock();
|
||||
f = vxlan_find_mac(vxlan, n->ha, vni);
|
||||
if (f && vxlan_addr_any(&(first_remote_rcu(f)->remote_ip))) {
|
||||
/* bridge-local neighbor */
|
||||
neigh_release(n);
|
||||
rcu_read_unlock();
|
||||
goto out;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
reply = arp_create(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip, sha,
|
||||
n->ha, sha);
|
||||
|
|
@ -2648,14 +2651,10 @@ static void vxlan_xmit_nh(struct sk_buff *skb, struct net_device *dev,
|
|||
memset(&nh_rdst, 0, sizeof(struct vxlan_rdst));
|
||||
hash = skb_get_hash(skb);
|
||||
|
||||
rcu_read_lock();
|
||||
nh = rcu_dereference(f->nh);
|
||||
if (!nh) {
|
||||
rcu_read_unlock();
|
||||
if (!nh)
|
||||
goto drop;
|
||||
}
|
||||
do_xmit = vxlan_fdb_nh_path_select(nh, hash, &nh_rdst);
|
||||
rcu_read_unlock();
|
||||
|
||||
if (likely(do_xmit))
|
||||
vxlan_xmit_one(skb, dev, vni, &nh_rdst, did_rsc);
|
||||
|
|
@ -2782,6 +2781,7 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
}
|
||||
|
||||
eth = eth_hdr(skb);
|
||||
rcu_read_lock();
|
||||
f = vxlan_find_mac(vxlan, eth->h_dest, vni);
|
||||
did_rsc = false;
|
||||
|
||||
|
|
@ -2804,7 +2804,7 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
vxlan_vnifilter_count(vxlan, vni, NULL,
|
||||
VXLAN_VNI_STATS_TX_DROPS, 0);
|
||||
kfree_skb_reason(skb, SKB_DROP_REASON_NO_TX_TARGET);
|
||||
return NETDEV_TX_OK;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2829,6 +2829,8 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
kfree_skb_reason(skb, SKB_DROP_REASON_NO_TX_TARGET);
|
||||
}
|
||||
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user