Skip to content

Commit 02bebe7

Browse files
idoschgregkh
authored andcommitted
vxlan: Add RCU read-side critical sections in the Tx path
[ Upstream commit 804b09b ] 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 <[email protected]> Signed-off-by: Ido Schimmel <[email protected]> Link: https://patch.msgid.link/[email protected] Reviewed-by: Nikolay Aleksandrov <[email protected]> Signed-off-by: Paolo Abeni <[email protected]> Stable-dep-of: 1f5d2fd ("vxlan: Fix NPD in {arp,neigh}_reduce() when using nexthop objects") Signed-off-by: Sasha Levin <[email protected]>
1 parent 9238419 commit 02bebe7

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
@@ -1909,12 +1909,15 @@ static int arp_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni)
19091909
goto out;
19101910
}
19111911

1912+
rcu_read_lock();
19121913
f = vxlan_find_mac(vxlan, n->ha, vni);
19131914
if (f && vxlan_addr_any(&(first_remote_rcu(f)->remote_ip))) {
19141915
/* bridge-local neighbor */
19151916
neigh_release(n);
1917+
rcu_read_unlock();
19161918
goto out;
19171919
}
1920+
rcu_read_unlock();
19181921

19191922
reply = arp_create(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip, sha,
19201923
n->ha, sha);
@@ -2632,14 +2635,10 @@ static void vxlan_xmit_nh(struct sk_buff *skb, struct net_device *dev,
26322635
memset(&nh_rdst, 0, sizeof(struct vxlan_rdst));
26332636
hash = skb_get_hash(skb);
26342637

2635-
rcu_read_lock();
26362638
nh = rcu_dereference(f->nh);
2637-
if (!nh) {
2638-
rcu_read_unlock();
2639+
if (!nh)
26392640
goto drop;
2640-
}
26412641
do_xmit = vxlan_fdb_nh_path_select(nh, hash, &nh_rdst);
2642-
rcu_read_unlock();
26432642

26442643
if (likely(do_xmit))
26452644
vxlan_xmit_one(skb, dev, vni, &nh_rdst, did_rsc);
@@ -2766,6 +2765,7 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
27662765
}
27672766

27682767
eth = eth_hdr(skb);
2768+
rcu_read_lock();
27692769
f = vxlan_find_mac(vxlan, eth->h_dest, vni);
27702770
did_rsc = false;
27712771

@@ -2788,7 +2788,7 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
27882788
vxlan_vnifilter_count(vxlan, vni, NULL,
27892789
VXLAN_VNI_STATS_TX_DROPS, 0);
27902790
kfree_skb_reason(skb, SKB_DROP_REASON_NO_TX_TARGET);
2791-
return NETDEV_TX_OK;
2791+
goto out;
27922792
}
27932793
}
27942794

@@ -2813,6 +2813,8 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
28132813
kfree_skb_reason(skb, SKB_DROP_REASON_NO_TX_TARGET);
28142814
}
28152815

2816+
out:
2817+
rcu_read_unlock();
28162818
return NETDEV_TX_OK;
28172819
}
28182820

0 commit comments

Comments
 (0)