Skip to content

Commit fdc953c

Browse files
author
CKI KWF Bot
committed
Merge: tunnels: stable backport for 10.2 phase 1
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-10/-/merge_requests/1533 JIRA: https://issues.redhat.com/browse/RHEL-115591 Upstream Status: linux.git Upstream fixes for vxlan. Signed-off-by: Guillaume Nault <gnault@redhat.com> Approved-by: Davide Caratti <dcaratti@redhat.com> Approved-by: Florian Westphal <fwestpha@redhat.com> Approved-by: Paolo Abeni <pabeni@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: CKI GitLab Kmaint Pipeline Bot <26919896-cki-kmaint-pipeline-bot@users.noreply.gitlab.com>
2 parents 49b162a + 1048a03 commit fdc953c

File tree

3 files changed

+28
-16
lines changed

3 files changed

+28
-16
lines changed

drivers/net/vxlan/vxlan_core.c

Lines changed: 20 additions & 12 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",
@@ -1913,6 +1913,7 @@ static int arp_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni)
19131913
n = neigh_lookup(&arp_tbl, &tip, dev);
19141914

19151915
if (n) {
1916+
struct vxlan_rdst *rdst = NULL;
19161917
struct vxlan_fdb *f;
19171918
struct sk_buff *reply;
19181919

@@ -1921,12 +1922,17 @@ static int arp_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni)
19211922
goto out;
19221923
}
19231924

1925+
rcu_read_lock();
19241926
f = vxlan_find_mac(vxlan, n->ha, vni);
1925-
if (f && vxlan_addr_any(&(first_remote_rcu(f)->remote_ip))) {
1927+
if (f)
1928+
rdst = first_remote_rcu(f);
1929+
if (rdst && vxlan_addr_any(&rdst->remote_ip)) {
19261930
/* bridge-local neighbor */
19271931
neigh_release(n);
1932+
rcu_read_unlock();
19281933
goto out;
19291934
}
1935+
rcu_read_unlock();
19301936

19311937
reply = arp_create(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip, sha,
19321938
n->ha, sha);
@@ -2077,6 +2083,7 @@ static int neigh_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni)
20772083
n = neigh_lookup(ipv6_stub->nd_tbl, &msg->target, dev);
20782084

20792085
if (n) {
2086+
struct vxlan_rdst *rdst = NULL;
20802087
struct vxlan_fdb *f;
20812088
struct sk_buff *reply;
20822089

@@ -2086,7 +2093,9 @@ static int neigh_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni)
20862093
}
20872094

20882095
f = vxlan_find_mac(vxlan, n->ha, vni);
2089-
if (f && vxlan_addr_any(&(first_remote_rcu(f)->remote_ip))) {
2096+
if (f)
2097+
rdst = first_remote_rcu(f);
2098+
if (rdst && vxlan_addr_any(&rdst->remote_ip)) {
20902099
/* bridge-local neighbor */
20912100
neigh_release(n);
20922101
goto out;
@@ -2653,14 +2662,10 @@ static void vxlan_xmit_nh(struct sk_buff *skb, struct net_device *dev,
26532662
memset(&nh_rdst, 0, sizeof(struct vxlan_rdst));
26542663
hash = skb_get_hash(skb);
26552664

2656-
rcu_read_lock();
26572665
nh = rcu_dereference(f->nh);
2658-
if (!nh) {
2659-
rcu_read_unlock();
2666+
if (!nh)
26602667
goto drop;
2661-
}
26622668
do_xmit = vxlan_fdb_nh_path_select(nh, hash, &nh_rdst);
2663-
rcu_read_unlock();
26642669

26652670
if (likely(do_xmit))
26662671
vxlan_xmit_one(skb, dev, vni, &nh_rdst, did_rsc);
@@ -2787,6 +2792,7 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
27872792
}
27882793

27892794
eth = eth_hdr(skb);
2795+
rcu_read_lock();
27902796
f = vxlan_find_mac(vxlan, eth->h_dest, vni);
27912797
did_rsc = false;
27922798

@@ -2809,7 +2815,7 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
28092815
vxlan_vnifilter_count(vxlan, vni, NULL,
28102816
VXLAN_VNI_STATS_TX_DROPS, 0);
28112817
kfree_skb_reason(skb, SKB_DROP_REASON_NO_TX_TARGET);
2812-
return NETDEV_TX_OK;
2818+
goto out;
28132819
}
28142820
}
28152821

@@ -2834,6 +2840,8 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
28342840
kfree_skb_reason(skb, SKB_DROP_REASON_NO_TX_TARGET);
28352841
}
28362842

2843+
out:
2844+
rcu_read_unlock();
28372845
return NETDEV_TX_OK;
28382846
}
28392847

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))

drivers/net/vxlan/vxlan_vnifilter.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -627,14 +627,20 @@ static void vxlan_vni_delete_group(struct vxlan_dev *vxlan,
627627
* default dst remote_ip previously added for this vni
628628
*/
629629
if (!vxlan_addr_any(&vninode->remote_ip) ||
630-
!vxlan_addr_any(&dst->remote_ip))
630+
!vxlan_addr_any(&dst->remote_ip)) {
631+
u32 hash_index = fdb_head_index(vxlan, all_zeros_mac,
632+
vninode->vni);
633+
634+
spin_lock_bh(&vxlan->hash_lock[hash_index]);
631635
__vxlan_fdb_delete(vxlan, all_zeros_mac,
632636
(vxlan_addr_any(&vninode->remote_ip) ?
633637
dst->remote_ip : vninode->remote_ip),
634638
vxlan->cfg.dst_port,
635639
vninode->vni, vninode->vni,
636640
dst->remote_ifindex,
637641
true);
642+
spin_unlock_bh(&vxlan->hash_lock[hash_index]);
643+
}
638644

639645
if (vxlan->dev->flags & IFF_UP) {
640646
if (vxlan_addr_multicast(&vninode->remote_ip) &&

0 commit comments

Comments
 (0)