Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Andrea Mayer and committed by
David S. Miller
49042c22 c5eb179e

+132
+39
include/net/l3mdev.h
··· 10 10 #include <net/dst.h> 11 11 #include <net/fib_rules.h> 12 12 13 + enum l3mdev_type { 14 + L3MDEV_TYPE_UNSPEC, 15 + L3MDEV_TYPE_VRF, 16 + __L3MDEV_TYPE_MAX 17 + }; 18 + 19 + #define L3MDEV_TYPE_MAX (__L3MDEV_TYPE_MAX - 1) 20 + 21 + typedef int (*lookup_by_table_id_t)(struct net *net, u32 table_d); 22 + 13 23 /** 14 24 * struct l3mdev_ops - l3mdev operations 15 25 * ··· 46 36 }; 47 37 48 38 #ifdef CONFIG_NET_L3_MASTER_DEV 39 + 40 + int l3mdev_table_lookup_register(enum l3mdev_type l3type, 41 + lookup_by_table_id_t fn); 42 + 43 + void l3mdev_table_lookup_unregister(enum l3mdev_type l3type, 44 + lookup_by_table_id_t fn); 45 + 46 + int l3mdev_ifindex_lookup_by_table_id(enum l3mdev_type l3type, struct net *net, 47 + u32 table_id); 49 48 50 49 int l3mdev_fib_rule_match(struct net *net, struct flowi *fl, 51 50 struct fib_lookup_arg *arg); ··· 297 278 struct sk_buff *l3mdev_ip6_out(struct sock *sk, struct sk_buff *skb) 298 279 { 299 280 return skb; 281 + } 282 + 283 + static inline 284 + int l3mdev_table_lookup_register(enum l3mdev_type l3type, 285 + lookup_by_table_id_t fn) 286 + { 287 + return -EOPNOTSUPP; 288 + } 289 + 290 + static inline 291 + void l3mdev_table_lookup_unregister(enum l3mdev_type l3type, 292 + lookup_by_table_id_t fn) 293 + { 294 + } 295 + 296 + static inline 297 + int l3mdev_ifindex_lookup_by_table_id(enum l3mdev_type l3type, struct net *net, 298 + u32 table_id) 299 + { 300 + return -ENODEV; 300 301 } 301 302 302 303 static inline
+93
net/l3mdev/l3mdev.c
··· 9 9 #include <net/fib_rules.h> 10 10 #include <net/l3mdev.h> 11 11 12 + static DEFINE_SPINLOCK(l3mdev_lock); 13 + 14 + struct l3mdev_handler { 15 + lookup_by_table_id_t dev_lookup; 16 + }; 17 + 18 + static struct l3mdev_handler l3mdev_handlers[L3MDEV_TYPE_MAX + 1]; 19 + 20 + static int l3mdev_check_type(enum l3mdev_type l3type) 21 + { 22 + if (l3type <= L3MDEV_TYPE_UNSPEC || l3type > L3MDEV_TYPE_MAX) 23 + return -EINVAL; 24 + 25 + return 0; 26 + } 27 + 28 + int l3mdev_table_lookup_register(enum l3mdev_type l3type, 29 + lookup_by_table_id_t fn) 30 + { 31 + struct l3mdev_handler *hdlr; 32 + int res; 33 + 34 + res = l3mdev_check_type(l3type); 35 + if (res) 36 + return res; 37 + 38 + hdlr = &l3mdev_handlers[l3type]; 39 + 40 + spin_lock(&l3mdev_lock); 41 + 42 + if (hdlr->dev_lookup) { 43 + res = -EBUSY; 44 + goto unlock; 45 + } 46 + 47 + hdlr->dev_lookup = fn; 48 + res = 0; 49 + 50 + unlock: 51 + spin_unlock(&l3mdev_lock); 52 + 53 + return res; 54 + } 55 + EXPORT_SYMBOL_GPL(l3mdev_table_lookup_register); 56 + 57 + void l3mdev_table_lookup_unregister(enum l3mdev_type l3type, 58 + lookup_by_table_id_t fn) 59 + { 60 + struct l3mdev_handler *hdlr; 61 + 62 + if (l3mdev_check_type(l3type)) 63 + return; 64 + 65 + hdlr = &l3mdev_handlers[l3type]; 66 + 67 + spin_lock(&l3mdev_lock); 68 + 69 + if (hdlr->dev_lookup == fn) 70 + hdlr->dev_lookup = NULL; 71 + 72 + spin_unlock(&l3mdev_lock); 73 + } 74 + EXPORT_SYMBOL_GPL(l3mdev_table_lookup_unregister); 75 + 76 + int l3mdev_ifindex_lookup_by_table_id(enum l3mdev_type l3type, 77 + struct net *net, u32 table_id) 78 + { 79 + lookup_by_table_id_t lookup; 80 + struct l3mdev_handler *hdlr; 81 + int ifindex = -EINVAL; 82 + int res; 83 + 84 + res = l3mdev_check_type(l3type); 85 + if (res) 86 + return res; 87 + 88 + hdlr = &l3mdev_handlers[l3type]; 89 + 90 + spin_lock(&l3mdev_lock); 91 + 92 + lookup = hdlr->dev_lookup; 93 + if (!lookup) 94 + goto unlock; 95 + 96 + ifindex = lookup(net, table_id); 97 + 98 + unlock: 99 + spin_unlock(&l3mdev_lock); 100 + 101 + return ifindex; 102 + } 103 + EXPORT_SYMBOL_GPL(l3mdev_ifindex_lookup_by_table_id); 104 + 12 105 /** 13 106 * l3mdev_master_ifindex - get index of L3 master device 14 107 * @dev: targeted interface