Skip to content

Commit 3924fa9

Browse files
committed
Merge branch 'vxlan-age-fdb-entries-based-on-rx-traffic'
Ido Schimmel says: ==================== vxlan: Age FDB entries based on Rx traffic tl;dr - This patchset prevents VXLAN FDB entries from lingering if traffic is only forwarded to a silent host. The VXLAN driver maintains two timestamps for each FDB entry: 'used' and 'updated'. The first is refreshed by both the Rx and Tx paths and the second is refreshed upon migration. The driver ages out entries according to their 'used' time which means that an entry can linger when traffic is only forwarded to a silent host that might have migrated to a different remote. This patchset solves the problem by adjusting the above semantics and aligning them to those of the bridge driver. That is, 'used' time is refreshed by the Tx path, 'updated' time is refresh by Rx path or user space updates and entries are aged out according to their 'updated' time. Patches #1-#2 perform small changes in how the 'used' and 'updated' fields are accessed. Patches #3-#5 refresh the 'updated' time where needed. Patch #6 flips the driver to age out FDB entries according to their 'updated' time. Patch #7 removes unnecessary updates to the 'used' time. Patch #8 extends a test case to cover aging of FDB entries in the presence of Tx traffic. ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 50f37fc + c467a98 commit 3924fa9

File tree

2 files changed

+21
-13
lines changed

2 files changed

+21
-13
lines changed

drivers/net/vxlan/vxlan_core.c

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -227,9 +227,9 @@ static int vxlan_fdb_info(struct sk_buff *skb, struct vxlan_dev *vxlan,
227227
be32_to_cpu(fdb->vni)))
228228
goto nla_put_failure;
229229

230-
ci.ndm_used = jiffies_to_clock_t(now - fdb->used);
230+
ci.ndm_used = jiffies_to_clock_t(now - READ_ONCE(fdb->used));
231231
ci.ndm_confirmed = 0;
232-
ci.ndm_updated = jiffies_to_clock_t(now - fdb->updated);
232+
ci.ndm_updated = jiffies_to_clock_t(now - READ_ONCE(fdb->updated));
233233
ci.ndm_refcnt = 0;
234234

235235
if (nla_put(skb, NDA_CACHEINFO, sizeof(ci), &ci))
@@ -434,8 +434,12 @@ static struct vxlan_fdb *vxlan_find_mac(struct vxlan_dev *vxlan,
434434
struct vxlan_fdb *f;
435435

436436
f = __vxlan_find_mac(vxlan, mac, vni);
437-
if (f && f->used != jiffies)
438-
f->used = jiffies;
437+
if (f) {
438+
unsigned long now = jiffies;
439+
440+
if (READ_ONCE(f->used) != now)
441+
WRITE_ONCE(f->used, now);
442+
}
439443

440444
return f;
441445
}
@@ -1009,12 +1013,10 @@ static int vxlan_fdb_update_existing(struct vxlan_dev *vxlan,
10091013
!(f->flags & NTF_VXLAN_ADDED_BY_USER)) {
10101014
if (f->state != state) {
10111015
f->state = state;
1012-
f->updated = jiffies;
10131016
notify = 1;
10141017
}
10151018
if (f->flags != fdb_flags) {
10161019
f->flags = fdb_flags;
1017-
f->updated = jiffies;
10181020
notify = 1;
10191021
}
10201022
}
@@ -1048,12 +1050,13 @@ static int vxlan_fdb_update_existing(struct vxlan_dev *vxlan,
10481050
}
10491051

10501052
if (ndm_flags & NTF_USE)
1051-
f->used = jiffies;
1053+
WRITE_ONCE(f->updated, jiffies);
10521054

10531055
if (notify) {
10541056
if (rd == NULL)
10551057
rd = first_remote_rtnl(f);
10561058

1059+
WRITE_ONCE(f->updated, jiffies);
10571060
err = vxlan_fdb_notify(vxlan, f, rd, RTM_NEWNEIGH,
10581061
swdev_notify, extack);
10591062
if (err)
@@ -1292,7 +1295,7 @@ int __vxlan_fdb_delete(struct vxlan_dev *vxlan,
12921295
struct vxlan_fdb *f;
12931296
int err = -ENOENT;
12941297

1295-
f = vxlan_find_mac(vxlan, addr, src_vni);
1298+
f = __vxlan_find_mac(vxlan, addr, src_vni);
12961299
if (!f)
12971300
return err;
12981301

@@ -1459,9 +1462,13 @@ static enum skb_drop_reason vxlan_snoop(struct net_device *dev,
14591462
ifindex = src_ifindex;
14601463
#endif
14611464

1462-
f = vxlan_find_mac(vxlan, src_mac, vni);
1465+
f = __vxlan_find_mac(vxlan, src_mac, vni);
14631466
if (likely(f)) {
14641467
struct vxlan_rdst *rdst = first_remote_rcu(f);
1468+
unsigned long now = jiffies;
1469+
1470+
if (READ_ONCE(f->updated) != now)
1471+
WRITE_ONCE(f->updated, now);
14651472

14661473
if (likely(vxlan_addr_equal(&rdst->remote_ip, src_ip) &&
14671474
rdst->remote_ifindex == ifindex))
@@ -1481,7 +1488,6 @@ static enum skb_drop_reason vxlan_snoop(struct net_device *dev,
14811488
src_mac, &rdst->remote_ip.sa, &src_ip->sa);
14821489

14831490
rdst->remote_ip = *src_ip;
1484-
f->updated = jiffies;
14851491
vxlan_fdb_notify(vxlan, f, rdst, RTM_NEWNEIGH, true, NULL);
14861492
} else {
14871493
u32 hash_index = fdb_head_index(vxlan, src_mac, vni);
@@ -2852,7 +2858,7 @@ static void vxlan_cleanup(struct timer_list *t)
28522858
if (f->flags & NTF_EXT_LEARNED)
28532859
continue;
28542860

2855-
timeout = f->used + vxlan->cfg.age_interval * HZ;
2861+
timeout = READ_ONCE(f->updated) + vxlan->cfg.age_interval * HZ;
28562862
if (time_before_eq(timeout, jiffies)) {
28572863
netdev_dbg(vxlan->dev,
28582864
"garbage collect %pM\n",
@@ -4765,7 +4771,7 @@ vxlan_fdb_offloaded_set(struct net_device *dev,
47654771

47664772
spin_lock_bh(&vxlan->hash_lock[hash_index]);
47674773

4768-
f = vxlan_find_mac(vxlan, fdb_info->eth_addr, fdb_info->vni);
4774+
f = __vxlan_find_mac(vxlan, fdb_info->eth_addr, fdb_info->vni);
47694775
if (!f)
47704776
goto out;
47714777

@@ -4821,7 +4827,7 @@ vxlan_fdb_external_learn_del(struct net_device *dev,
48214827
hash_index = fdb_head_index(vxlan, fdb_info->eth_addr, fdb_info->vni);
48224828
spin_lock_bh(&vxlan->hash_lock[hash_index]);
48234829

4824-
f = vxlan_find_mac(vxlan, fdb_info->eth_addr, fdb_info->vni);
4830+
f = __vxlan_find_mac(vxlan, fdb_info->eth_addr, fdb_info->vni);
48254831
if (!f)
48264832
err = -ENOENT;
48274833
else if (f->flags & NTF_EXT_LEARNED)

tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,8 @@ test_learning()
740740

741741
vxlan_flood_test $mac $dst 0 10 0
742742

743+
# The entry should age out when it only forwards traffic
744+
$MZ $h1 -c 50 -d 1sec -p 64 -b $mac -B $dst -t icmp -q &
743745
sleep 60
744746

745747
bridge fdb show brport vx1 | grep $mac | grep -q self

0 commit comments

Comments
 (0)