mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-05 05:59:10 +08:00
vxlan: Introduce FDB key structure
In preparation for converting the FDB table to rhashtable, introduce a key structure that includes the MAC address and source VNI. No functional changes intended. Reviewed-by: Petr Machata <petrm@nvidia.com> Signed-off-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20250415121143.345227-15-idosch@nvidia.com Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
committed by
Paolo Abeni
parent
20c76dadc7
commit
f13f3b4157
@@ -186,7 +186,7 @@ static int vxlan_fdb_info(struct sk_buff *skb, struct vxlan_dev *vxlan,
|
||||
} else if (nh) {
|
||||
ndm->ndm_family = nh_family;
|
||||
}
|
||||
send_eth = !is_zero_ether_addr(fdb->eth_addr);
|
||||
send_eth = !is_zero_ether_addr(fdb->key.eth_addr);
|
||||
} else
|
||||
ndm->ndm_family = AF_BRIDGE;
|
||||
ndm->ndm_state = fdb->state;
|
||||
@@ -201,7 +201,7 @@ static int vxlan_fdb_info(struct sk_buff *skb, struct vxlan_dev *vxlan,
|
||||
peernet2id(dev_net(vxlan->dev), vxlan->net)))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (send_eth && nla_put(skb, NDA_LLADDR, ETH_ALEN, &fdb->eth_addr))
|
||||
if (send_eth && nla_put(skb, NDA_LLADDR, ETH_ALEN, &fdb->key.eth_addr))
|
||||
goto nla_put_failure;
|
||||
if (nh) {
|
||||
if (nla_put_u32(skb, NDA_NH_ID, nh_id))
|
||||
@@ -223,9 +223,9 @@ static int vxlan_fdb_info(struct sk_buff *skb, struct vxlan_dev *vxlan,
|
||||
goto nla_put_failure;
|
||||
}
|
||||
|
||||
if ((vxlan->cfg.flags & VXLAN_F_COLLECT_METADATA) && fdb->vni &&
|
||||
if ((vxlan->cfg.flags & VXLAN_F_COLLECT_METADATA) && fdb->key.vni &&
|
||||
nla_put_u32(skb, NDA_SRC_VNI,
|
||||
be32_to_cpu(fdb->vni)))
|
||||
be32_to_cpu(fdb->key.vni)))
|
||||
goto nla_put_failure;
|
||||
|
||||
ci.ndm_used = jiffies_to_clock_t(now - READ_ONCE(fdb->used));
|
||||
@@ -293,8 +293,8 @@ static void vxlan_fdb_switchdev_notifier_info(const struct vxlan_dev *vxlan,
|
||||
fdb_info->remote_port = rd->remote_port;
|
||||
fdb_info->remote_vni = rd->remote_vni;
|
||||
fdb_info->remote_ifindex = rd->remote_ifindex;
|
||||
memcpy(fdb_info->eth_addr, fdb->eth_addr, ETH_ALEN);
|
||||
fdb_info->vni = fdb->vni;
|
||||
memcpy(fdb_info->eth_addr, fdb->key.eth_addr, ETH_ALEN);
|
||||
fdb_info->vni = fdb->key.vni;
|
||||
fdb_info->offloaded = rd->offloaded;
|
||||
fdb_info->added_by_user = fdb->flags & NTF_VXLAN_ADDED_BY_USER;
|
||||
}
|
||||
@@ -366,7 +366,7 @@ static void vxlan_fdb_miss(struct vxlan_dev *vxlan, const u8 eth_addr[ETH_ALEN])
|
||||
};
|
||||
struct vxlan_rdst remote = { };
|
||||
|
||||
memcpy(f.eth_addr, eth_addr, ETH_ALEN);
|
||||
memcpy(f.key.eth_addr, eth_addr, ETH_ALEN);
|
||||
|
||||
vxlan_fdb_notify(vxlan, &f, &remote, RTM_GETNEIGH, true, NULL);
|
||||
}
|
||||
@@ -416,9 +416,9 @@ static struct vxlan_fdb *vxlan_find_mac_rcu(struct vxlan_dev *vxlan,
|
||||
struct vxlan_fdb *f;
|
||||
|
||||
hlist_for_each_entry_rcu(f, head, hlist) {
|
||||
if (ether_addr_equal(mac, f->eth_addr)) {
|
||||
if (ether_addr_equal(mac, f->key.eth_addr)) {
|
||||
if (vxlan->cfg.flags & VXLAN_F_COLLECT_METADATA) {
|
||||
if (vni == f->vni)
|
||||
if (vni == f->key.vni)
|
||||
return f;
|
||||
} else {
|
||||
return f;
|
||||
@@ -539,7 +539,7 @@ int vxlan_fdb_replay(const struct net_device *dev, __be32 vni,
|
||||
|
||||
spin_lock_bh(&vxlan->hash_lock);
|
||||
hlist_for_each_entry(f, &vxlan->fdb_list, fdb_node) {
|
||||
if (f->vni == vni) {
|
||||
if (f->key.vni == vni) {
|
||||
list_for_each_entry(rdst, &f->remotes, list) {
|
||||
rc = vxlan_fdb_notify_one(nb, vxlan, f, rdst,
|
||||
extack);
|
||||
@@ -569,7 +569,7 @@ void vxlan_fdb_clear_offload(const struct net_device *dev, __be32 vni)
|
||||
|
||||
spin_lock_bh(&vxlan->hash_lock);
|
||||
hlist_for_each_entry(f, &vxlan->fdb_list, fdb_node) {
|
||||
if (f->vni == vni) {
|
||||
if (f->key.vni == vni) {
|
||||
list_for_each_entry(rdst, &f->remotes, list)
|
||||
rdst->offloaded = false;
|
||||
}
|
||||
@@ -812,15 +812,16 @@ static struct vxlan_fdb *vxlan_fdb_alloc(struct vxlan_dev *vxlan, const u8 *mac,
|
||||
f = kmalloc(sizeof(*f), GFP_ATOMIC);
|
||||
if (!f)
|
||||
return NULL;
|
||||
memset(&f->key, 0, sizeof(f->key));
|
||||
f->state = state;
|
||||
f->flags = ndm_flags;
|
||||
f->updated = f->used = jiffies;
|
||||
f->vni = src_vni;
|
||||
f->key.vni = src_vni;
|
||||
f->nh = NULL;
|
||||
RCU_INIT_POINTER(f->vdev, vxlan);
|
||||
INIT_LIST_HEAD(&f->nh_list);
|
||||
INIT_LIST_HEAD(&f->remotes);
|
||||
memcpy(f->eth_addr, mac, ETH_ALEN);
|
||||
memcpy(f->key.eth_addr, mac, ETH_ALEN);
|
||||
|
||||
return f;
|
||||
}
|
||||
@@ -959,7 +960,7 @@ static void vxlan_fdb_destroy(struct vxlan_dev *vxlan, struct vxlan_fdb *f,
|
||||
{
|
||||
struct vxlan_rdst *rd;
|
||||
|
||||
netdev_dbg(vxlan->dev, "delete %pM\n", f->eth_addr);
|
||||
netdev_dbg(vxlan->dev, "delete %pM\n", f->key.eth_addr);
|
||||
|
||||
--vxlan->addrcnt;
|
||||
if (do_notify) {
|
||||
@@ -1031,8 +1032,8 @@ static int vxlan_fdb_update_existing(struct vxlan_dev *vxlan,
|
||||
|
||||
if ((flags & NLM_F_REPLACE)) {
|
||||
/* Only change unicasts */
|
||||
if (!(is_multicast_ether_addr(f->eth_addr) ||
|
||||
is_zero_ether_addr(f->eth_addr))) {
|
||||
if (!(is_multicast_ether_addr(f->key.eth_addr) ||
|
||||
is_zero_ether_addr(f->key.eth_addr))) {
|
||||
if (nhid) {
|
||||
rc = vxlan_fdb_nh_update(vxlan, f, nhid, extack);
|
||||
if (rc < 0)
|
||||
@@ -1048,8 +1049,8 @@ static int vxlan_fdb_update_existing(struct vxlan_dev *vxlan,
|
||||
}
|
||||
}
|
||||
if ((flags & NLM_F_APPEND) &&
|
||||
(is_multicast_ether_addr(f->eth_addr) ||
|
||||
is_zero_ether_addr(f->eth_addr))) {
|
||||
(is_multicast_ether_addr(f->key.eth_addr) ||
|
||||
is_zero_ether_addr(f->key.eth_addr))) {
|
||||
rc = vxlan_fdb_append(f, ip, port, vni, ifindex, &rd);
|
||||
|
||||
if (rc < 0)
|
||||
@@ -2853,7 +2854,7 @@ static void vxlan_cleanup(struct timer_list *t)
|
||||
spin_lock(&vxlan->hash_lock);
|
||||
if (!hlist_unhashed(&f->fdb_node)) {
|
||||
netdev_dbg(vxlan->dev, "garbage collect %pM\n",
|
||||
f->eth_addr);
|
||||
f->key.eth_addr);
|
||||
f->state = NUD_STALE;
|
||||
vxlan_fdb_destroy(vxlan, f, true, true);
|
||||
}
|
||||
@@ -2972,7 +2973,8 @@ struct vxlan_fdb_flush_desc {
|
||||
static bool vxlan_fdb_is_default_entry(const struct vxlan_fdb *f,
|
||||
const struct vxlan_dev *vxlan)
|
||||
{
|
||||
return is_zero_ether_addr(f->eth_addr) && f->vni == vxlan->cfg.vni;
|
||||
return is_zero_ether_addr(f->key.eth_addr) &&
|
||||
f->key.vni == vxlan->cfg.vni;
|
||||
}
|
||||
|
||||
static bool vxlan_fdb_nhid_matches(const struct vxlan_fdb *f, u32 nhid)
|
||||
@@ -2995,7 +2997,7 @@ static bool vxlan_fdb_flush_matches(const struct vxlan_fdb *f,
|
||||
if (desc->ignore_default_entry && vxlan_fdb_is_default_entry(f, vxlan))
|
||||
return false;
|
||||
|
||||
if (desc->src_vni && f->vni != desc->src_vni)
|
||||
if (desc->src_vni && f->key.vni != desc->src_vni)
|
||||
return false;
|
||||
|
||||
if (desc->nhid && !vxlan_fdb_nhid_matches(f, desc->nhid))
|
||||
|
||||
@@ -24,6 +24,11 @@ struct vxlan_net {
|
||||
struct notifier_block nexthop_notifier_block;
|
||||
};
|
||||
|
||||
struct vxlan_fdb_key {
|
||||
u8 eth_addr[ETH_ALEN];
|
||||
__be32 vni;
|
||||
};
|
||||
|
||||
/* Forwarding table entry */
|
||||
struct vxlan_fdb {
|
||||
struct hlist_node hlist; /* linked list of entries */
|
||||
@@ -31,9 +36,8 @@ struct vxlan_fdb {
|
||||
unsigned long updated; /* jiffies */
|
||||
unsigned long used;
|
||||
struct list_head remotes;
|
||||
u8 eth_addr[ETH_ALEN];
|
||||
struct vxlan_fdb_key key;
|
||||
u16 state; /* see ndm_state */
|
||||
__be32 vni;
|
||||
u16 flags; /* see ndm_flags and below */
|
||||
struct list_head nh_list;
|
||||
struct hlist_node fdb_node;
|
||||
|
||||
Reference in New Issue
Block a user