mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 20:00:53 +07:00
vxlan: support for nexthop notifiers
vxlan driver registers for nexthop add/del notifiers to cleanup fdb entries pointing to such nexthops. Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
8590ceedb7
commit
c7cdbe2efc
@ -81,6 +81,7 @@ struct vxlan_fdb {
|
|||||||
u16 flags; /* see ndm_flags and below */
|
u16 flags; /* see ndm_flags and below */
|
||||||
struct list_head nh_list;
|
struct list_head nh_list;
|
||||||
struct nexthop __rcu *nh;
|
struct nexthop __rcu *nh;
|
||||||
|
struct vxlan_dev *vdev;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NTF_VXLAN_ADDED_BY_USER 0x100
|
#define NTF_VXLAN_ADDED_BY_USER 0x100
|
||||||
@ -813,8 +814,9 @@ static int vxlan_gro_complete(struct sock *sk, struct sk_buff *skb, int nhoff)
|
|||||||
return eth_gro_complete(skb, nhoff + sizeof(struct vxlanhdr));
|
return eth_gro_complete(skb, nhoff + sizeof(struct vxlanhdr));
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct vxlan_fdb *vxlan_fdb_alloc(const u8 *mac, __u16 state,
|
static struct vxlan_fdb *vxlan_fdb_alloc(struct vxlan_dev *vxlan, const u8 *mac,
|
||||||
__be32 src_vni, __u16 ndm_flags)
|
__u16 state, __be32 src_vni,
|
||||||
|
__u16 ndm_flags)
|
||||||
{
|
{
|
||||||
struct vxlan_fdb *f;
|
struct vxlan_fdb *f;
|
||||||
|
|
||||||
@ -826,6 +828,7 @@ static struct vxlan_fdb *vxlan_fdb_alloc(const u8 *mac, __u16 state,
|
|||||||
f->updated = f->used = jiffies;
|
f->updated = f->used = jiffies;
|
||||||
f->vni = src_vni;
|
f->vni = src_vni;
|
||||||
f->nh = NULL;
|
f->nh = NULL;
|
||||||
|
f->vdev = vxlan;
|
||||||
INIT_LIST_HEAD(&f->nh_list);
|
INIT_LIST_HEAD(&f->nh_list);
|
||||||
INIT_LIST_HEAD(&f->remotes);
|
INIT_LIST_HEAD(&f->remotes);
|
||||||
memcpy(f->eth_addr, mac, ETH_ALEN);
|
memcpy(f->eth_addr, mac, ETH_ALEN);
|
||||||
@ -923,7 +926,7 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan,
|
|||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
|
|
||||||
netdev_dbg(vxlan->dev, "add %pM -> %pIS\n", mac, ip);
|
netdev_dbg(vxlan->dev, "add %pM -> %pIS\n", mac, ip);
|
||||||
f = vxlan_fdb_alloc(mac, state, src_vni, ndm_flags);
|
f = vxlan_fdb_alloc(vxlan, mac, state, src_vni, ndm_flags);
|
||||||
if (!f)
|
if (!f)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
@ -988,6 +991,7 @@ static void vxlan_fdb_destroy(struct vxlan_dev *vxlan, struct vxlan_fdb *f,
|
|||||||
}
|
}
|
||||||
|
|
||||||
hlist_del_rcu(&f->hlist);
|
hlist_del_rcu(&f->hlist);
|
||||||
|
f->vdev = NULL;
|
||||||
call_rcu(&f->rcu, vxlan_fdb_free);
|
call_rcu(&f->rcu, vxlan_fdb_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4598,6 +4602,25 @@ static struct notifier_block vxlan_switchdev_notifier_block __read_mostly = {
|
|||||||
.notifier_call = vxlan_switchdev_event,
|
.notifier_call = vxlan_switchdev_event,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int vxlan_nexthop_event(struct notifier_block *nb,
|
||||||
|
unsigned long event, void *ptr)
|
||||||
|
{
|
||||||
|
struct nexthop *nh = ptr;
|
||||||
|
struct vxlan_fdb *fdb, *tmp;
|
||||||
|
|
||||||
|
if (!nh || event != NEXTHOP_EVENT_DEL)
|
||||||
|
return NOTIFY_DONE;
|
||||||
|
|
||||||
|
list_for_each_entry_safe(fdb, tmp, &nh->fdb_list, nh_list)
|
||||||
|
vxlan_fdb_destroy(fdb->vdev, fdb, false, false);
|
||||||
|
|
||||||
|
return NOTIFY_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct notifier_block vxlan_nexthop_notifier_block __read_mostly = {
|
||||||
|
.notifier_call = vxlan_nexthop_event,
|
||||||
|
};
|
||||||
|
|
||||||
static __net_init int vxlan_init_net(struct net *net)
|
static __net_init int vxlan_init_net(struct net *net)
|
||||||
{
|
{
|
||||||
struct vxlan_net *vn = net_generic(net, vxlan_net_id);
|
struct vxlan_net *vn = net_generic(net, vxlan_net_id);
|
||||||
@ -4609,7 +4632,7 @@ static __net_init int vxlan_init_net(struct net *net)
|
|||||||
for (h = 0; h < PORT_HASH_SIZE; ++h)
|
for (h = 0; h < PORT_HASH_SIZE; ++h)
|
||||||
INIT_HLIST_HEAD(&vn->sock_list[h]);
|
INIT_HLIST_HEAD(&vn->sock_list[h]);
|
||||||
|
|
||||||
return 0;
|
return register_nexthop_notifier(net, &vxlan_nexthop_notifier_block);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vxlan_destroy_tunnels(struct net *net, struct list_head *head)
|
static void vxlan_destroy_tunnels(struct net *net, struct list_head *head)
|
||||||
@ -4641,6 +4664,8 @@ static void __net_exit vxlan_exit_batch_net(struct list_head *net_list)
|
|||||||
LIST_HEAD(list);
|
LIST_HEAD(list);
|
||||||
|
|
||||||
rtnl_lock();
|
rtnl_lock();
|
||||||
|
list_for_each_entry(net, net_list, exit_list)
|
||||||
|
unregister_nexthop_notifier(net, &vxlan_nexthop_notifier_block);
|
||||||
list_for_each_entry(net, net_list, exit_list)
|
list_for_each_entry(net, net_list, exit_list)
|
||||||
vxlan_destroy_tunnels(net, &list);
|
vxlan_destroy_tunnels(net, &list);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user