l3mdev: add infrastructure for table to VRF mapping
Add infrastructure to l3mdev (the core code for Layer 3 master devices) in order to find out the corresponding VRF device for a given table id. Therefore, the l3mdev implementations: - can register a callback that returns the device index of the l3mdev associated with a given table id; - can offer the lookup function (table to VRF device). Signed-off-by: Andrea Mayer <andrea.mayer@uniroma2.it> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
c5eb179edd
commit
49042c220b
|
@ -10,6 +10,16 @@
|
|||
#include <net/dst.h>
|
||||
#include <net/fib_rules.h>
|
||||
|
||||
enum l3mdev_type {
|
||||
L3MDEV_TYPE_UNSPEC,
|
||||
L3MDEV_TYPE_VRF,
|
||||
__L3MDEV_TYPE_MAX
|
||||
};
|
||||
|
||||
#define L3MDEV_TYPE_MAX (__L3MDEV_TYPE_MAX - 1)
|
||||
|
||||
typedef int (*lookup_by_table_id_t)(struct net *net, u32 table_d);
|
||||
|
||||
/**
|
||||
* struct l3mdev_ops - l3mdev operations
|
||||
*
|
||||
|
@ -37,6 +47,15 @@ struct l3mdev_ops {
|
|||
|
||||
#ifdef CONFIG_NET_L3_MASTER_DEV
|
||||
|
||||
int l3mdev_table_lookup_register(enum l3mdev_type l3type,
|
||||
lookup_by_table_id_t fn);
|
||||
|
||||
void l3mdev_table_lookup_unregister(enum l3mdev_type l3type,
|
||||
lookup_by_table_id_t fn);
|
||||
|
||||
int l3mdev_ifindex_lookup_by_table_id(enum l3mdev_type l3type, struct net *net,
|
||||
u32 table_id);
|
||||
|
||||
int l3mdev_fib_rule_match(struct net *net, struct flowi *fl,
|
||||
struct fib_lookup_arg *arg);
|
||||
|
||||
|
@ -280,6 +299,26 @@ struct sk_buff *l3mdev_ip6_out(struct sock *sk, struct sk_buff *skb)
|
|||
return skb;
|
||||
}
|
||||
|
||||
static inline
|
||||
int l3mdev_table_lookup_register(enum l3mdev_type l3type,
|
||||
lookup_by_table_id_t fn)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline
|
||||
void l3mdev_table_lookup_unregister(enum l3mdev_type l3type,
|
||||
lookup_by_table_id_t fn)
|
||||
{
|
||||
}
|
||||
|
||||
static inline
|
||||
int l3mdev_ifindex_lookup_by_table_id(enum l3mdev_type l3type, struct net *net,
|
||||
u32 table_id)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline
|
||||
int l3mdev_fib_rule_match(struct net *net, struct flowi *fl,
|
||||
struct fib_lookup_arg *arg)
|
||||
|
|
|
@ -9,6 +9,99 @@
|
|||
#include <net/fib_rules.h>
|
||||
#include <net/l3mdev.h>
|
||||
|
||||
static DEFINE_SPINLOCK(l3mdev_lock);
|
||||
|
||||
struct l3mdev_handler {
|
||||
lookup_by_table_id_t dev_lookup;
|
||||
};
|
||||
|
||||
static struct l3mdev_handler l3mdev_handlers[L3MDEV_TYPE_MAX + 1];
|
||||
|
||||
static int l3mdev_check_type(enum l3mdev_type l3type)
|
||||
{
|
||||
if (l3type <= L3MDEV_TYPE_UNSPEC || l3type > L3MDEV_TYPE_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int l3mdev_table_lookup_register(enum l3mdev_type l3type,
|
||||
lookup_by_table_id_t fn)
|
||||
{
|
||||
struct l3mdev_handler *hdlr;
|
||||
int res;
|
||||
|
||||
res = l3mdev_check_type(l3type);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
hdlr = &l3mdev_handlers[l3type];
|
||||
|
||||
spin_lock(&l3mdev_lock);
|
||||
|
||||
if (hdlr->dev_lookup) {
|
||||
res = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
hdlr->dev_lookup = fn;
|
||||
res = 0;
|
||||
|
||||
unlock:
|
||||
spin_unlock(&l3mdev_lock);
|
||||
|
||||
return res;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(l3mdev_table_lookup_register);
|
||||
|
||||
void l3mdev_table_lookup_unregister(enum l3mdev_type l3type,
|
||||
lookup_by_table_id_t fn)
|
||||
{
|
||||
struct l3mdev_handler *hdlr;
|
||||
|
||||
if (l3mdev_check_type(l3type))
|
||||
return;
|
||||
|
||||
hdlr = &l3mdev_handlers[l3type];
|
||||
|
||||
spin_lock(&l3mdev_lock);
|
||||
|
||||
if (hdlr->dev_lookup == fn)
|
||||
hdlr->dev_lookup = NULL;
|
||||
|
||||
spin_unlock(&l3mdev_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(l3mdev_table_lookup_unregister);
|
||||
|
||||
int l3mdev_ifindex_lookup_by_table_id(enum l3mdev_type l3type,
|
||||
struct net *net, u32 table_id)
|
||||
{
|
||||
lookup_by_table_id_t lookup;
|
||||
struct l3mdev_handler *hdlr;
|
||||
int ifindex = -EINVAL;
|
||||
int res;
|
||||
|
||||
res = l3mdev_check_type(l3type);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
hdlr = &l3mdev_handlers[l3type];
|
||||
|
||||
spin_lock(&l3mdev_lock);
|
||||
|
||||
lookup = hdlr->dev_lookup;
|
||||
if (!lookup)
|
||||
goto unlock;
|
||||
|
||||
ifindex = lookup(net, table_id);
|
||||
|
||||
unlock:
|
||||
spin_unlock(&l3mdev_lock);
|
||||
|
||||
return ifindex;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(l3mdev_ifindex_lookup_by_table_id);
|
||||
|
||||
/**
|
||||
* l3mdev_master_ifindex - get index of L3 master device
|
||||
* @dev: targeted interface
|
||||
|
|
Loading…
Reference in New Issue