diff options
author | Andrea Mayer <andrea.mayer@uniroma2.it> | 2020-06-20 00:54:46 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2020-06-20 17:22:23 -0700 |
commit | a59a8ffd4a1bc413c1e0169cf8a31cf9b4237264 (patch) | |
tree | 577d33d3c535bf12713c810870c35f0fffd32d7e /drivers/net/vrf.c | |
parent | 33306f1aaf82ba7dd072d4d7b97de63b1033cce3 (diff) | |
download | linux-a59a8ffd4a1bc413c1e0169cf8a31cf9b4237264.tar.bz2 |
vrf: add l3mdev registration for table to VRF device lookup
During the initialization phase of the VRF module, the callback for table
to VRF device lookup is registered in l3mdev.
Signed-off-by: Andrea Mayer <andrea.mayer@uniroma2.it>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/vrf.c')
-rw-r--r-- | drivers/net/vrf.c | 59 |
1 files changed, 55 insertions, 4 deletions
diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c index c53e57354d2c..46599606ff10 100644 --- a/drivers/net/vrf.c +++ b/drivers/net/vrf.c @@ -183,6 +183,19 @@ static struct vrf_map *netns_vrf_map_by_dev(struct net_device *dev) return netns_vrf_map(dev_net(dev)); } +static int vrf_map_elem_get_vrf_ifindex(struct vrf_map_elem *me) +{ + struct list_head *me_head = &me->vrf_list; + struct net_vrf *vrf; + + if (list_empty(me_head)) + return -ENODEV; + + vrf = list_first_entry(me_head, struct net_vrf, me_list); + + return vrf->ifindex; +} + static struct vrf_map_elem *vrf_map_elem_alloc(gfp_t flags) { struct vrf_map_elem *me; @@ -384,6 +397,34 @@ unlock: vrf_map_unlock(vmap); } +/* return the vrf device index associated with the table_id */ +static int vrf_ifindex_lookup_by_table_id(struct net *net, u32 table_id) +{ + struct vrf_map *vmap = netns_vrf_map(net); + struct vrf_map_elem *me; + int ifindex; + + vrf_map_lock(vmap); + + if (!vmap->strict_mode) { + ifindex = -EPERM; + goto unlock; + } + + me = vrf_map_lookup_elem(vmap, table_id); + if (!me) { + ifindex = -ENODEV; + goto unlock; + } + + ifindex = vrf_map_elem_get_vrf_ifindex(me); + +unlock: + vrf_map_unlock(vmap); + + return ifindex; +} + /* by default VRF devices do not have a qdisc and are expected * to be created with only a single queue. */ @@ -1847,14 +1888,24 @@ static int __init vrf_init_module(void) if (rc < 0) goto error; + rc = l3mdev_table_lookup_register(L3MDEV_TYPE_VRF, + vrf_ifindex_lookup_by_table_id); + if (rc < 0) + goto unreg_pernet; + rc = rtnl_link_register(&vrf_link_ops); - if (rc < 0) { - unregister_pernet_subsys(&vrf_net_ops); - goto error; - } + if (rc < 0) + goto table_lookup_unreg; return 0; +table_lookup_unreg: + l3mdev_table_lookup_unregister(L3MDEV_TYPE_VRF, + vrf_ifindex_lookup_by_table_id); + +unreg_pernet: + unregister_pernet_subsys(&vrf_net_ops); + error: unregister_netdevice_notifier(&vrf_notifier_block); return rc; |