vxlan: Always refresh FDB 'updated' time when learning is enabled
authorIdo Schimmel <idosch@nvidia.com>
Tue, 4 Feb 2025 14:55:44 +0000 (16:55 +0200)
committerJakub Kicinski <kuba@kernel.org>
Thu, 6 Feb 2025 02:53:57 +0000 (18:53 -0800)
Currently, when learning is enabled and a packet is received from the
expected remote, the 'updated' field of the FDB entry is not refreshed.
This will become a problem when we switch the VXLAN driver to age out
entries based on the 'updated' field.

Solve this by always refreshing an FDB entry when we receive a packet
with a matching source MAC address, regardless if it was received via
the expected remote or not as it indicates the host is alive. This is
consistent with the bridge driver's FDB.

Reviewed-by: Petr Machata <petrm@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Link: https://patch.msgid.link/20250204145549.1216254-4-idosch@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/vxlan/vxlan_core.c

index 676a93ce3a19726bc85be28ce52b9653314b3c50..36cb06a56aca9a70750f997f9829ce1b0db39205 100644 (file)
@@ -1466,6 +1466,10 @@ static enum skb_drop_reason vxlan_snoop(struct net_device *dev,
        f = vxlan_find_mac(vxlan, src_mac, vni);
        if (likely(f)) {
                struct vxlan_rdst *rdst = first_remote_rcu(f);
+               unsigned long now = jiffies;
+
+               if (READ_ONCE(f->updated) != now)
+                       WRITE_ONCE(f->updated, now);
 
                if (likely(vxlan_addr_equal(&rdst->remote_ip, src_ip) &&
                           rdst->remote_ifindex == ifindex))
@@ -1485,7 +1489,6 @@ static enum skb_drop_reason vxlan_snoop(struct net_device *dev,
                                    src_mac, &rdst->remote_ip.sa, &src_ip->sa);
 
                rdst->remote_ip = *src_ip;
-               WRITE_ONCE(f->updated, jiffies);
                vxlan_fdb_notify(vxlan, f, rdst, RTM_NEWNEIGH, true, NULL);
        } else {
                u32 hash_index = fdb_head_index(vxlan, src_mac, vni);