summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid Ahern <dsa@cumulusnetworks.com>2015-08-13 16:59:10 -0400
committerDavid S. Miller <davem@davemloft.net>2015-08-14 01:43:22 -0400
commit193125dbd8eb292d88feb201f030889b488b0a02 (patch)
tree945b31e0d4bb51d479771ed3a70948f59f23a775 /drivers
parent9972f134a273d6dc52d912a3513fa06b426de9b4 (diff)
net: Introduce VRF device driver
This driver borrows heavily from IPvlan and teaming drivers. Routing domains (VRF-lite) are created by instantiating a VRF master device with an associated table and enslaving all routed interfaces that participate in the domain. As part of the enslavement, all connected routes for the enslaved devices are moved to the table associated with the VRF device. Outgoing sockets must bind to the VRF device to function. Standard FIB rules bind the VRF device to tables and regular fib rule processing is followed. Routed traffic through the box, is forwarded by using the VRF device as the IIF and following the IIF rule to a table that is mated with the VRF. Example: Create vrf 1: ip link add vrf1 type vrf table 5 ip rule add iif vrf1 table 5 ip rule add oif vrf1 table 5 ip route add table 5 prohibit default ip link set vrf1 up Add interface to vrf 1: ip link set eth1 master vrf1 Signed-off-by: Shrijeet Mukherjee <shm@cumulusnetworks.com> Signed-off-by: David Ahern <dsa@cumulusnetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/Kconfig7
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/vrf.c685
3 files changed, 693 insertions, 0 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index c18f9e62a9fa..e58468b02987 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -297,6 +297,13 @@ config NLMON
297 diagnostics, etc. This is mostly intended for developers or support 297 diagnostics, etc. This is mostly intended for developers or support
298 to debug netlink issues. If unsure, say N. 298 to debug netlink issues. If unsure, say N.
299 299
300config NET_VRF
301 tristate "Virtual Routing and Forwarding (Lite)"
302 depends on IP_MULTIPLE_TABLES && IPV6_MULTIPLE_TABLES
303 ---help---
304 This option enables the support for mapping interfaces into VRF's. The
305 support enables VRF devices.
306
300endif # NET_CORE 307endif # NET_CORE
301 308
302config SUNGEM_PHY 309config SUNGEM_PHY
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index c12cb22478a7..ca16dd689b36 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_VIRTIO_NET) += virtio_net.o
25obj-$(CONFIG_VXLAN) += vxlan.o 25obj-$(CONFIG_VXLAN) += vxlan.o
26obj-$(CONFIG_GENEVE) += geneve.o 26obj-$(CONFIG_GENEVE) += geneve.o
27obj-$(CONFIG_NLMON) += nlmon.o 27obj-$(CONFIG_NLMON) += nlmon.o
28obj-$(CONFIG_NET_VRF) += vrf.o
28 29
29# 30#
30# Networking Drivers 31# Networking Drivers
diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
new file mode 100644
index 000000000000..95097cb79354
--- /dev/null
+++ b/drivers/net/vrf.c
@@ -0,0 +1,685 @@
1/*
2 * vrf.c: device driver to encapsulate a VRF space
3 *
4 * Copyright (c) 2015 Cumulus Networks. All rights reserved.
5 * Copyright (c) 2015 Shrijeet Mukherjee <shm@cumulusnetworks.com>
6 * Copyright (c) 2015 David Ahern <dsa@cumulusnetworks.com>
7 *
8 * Based on dummy, team and ipvlan drivers
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 */
15
16#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/netdevice.h>
19#include <linux/etherdevice.h>
20#include <linux/ip.h>
21#include <linux/init.h>
22#include <linux/moduleparam.h>
23#include <linux/netfilter.h>
24#include <linux/rtnetlink.h>
25#include <net/rtnetlink.h>
26#include <linux/u64_stats_sync.h>
27#include <linux/hashtable.h>
28
29#include <linux/inetdevice.h>
30#include <net/ip.h>
31#include <net/ip_fib.h>
32#include <net/ip6_route.h>
33#include <net/rtnetlink.h>
34#include <net/route.h>
35#include <net/addrconf.h>
36#include <net/vrf.h>
37
38#define DRV_NAME "vrf"
39#define DRV_VERSION "1.0"
40
41#define vrf_is_slave(dev) ((dev)->flags & IFF_SLAVE)
42
43#define vrf_master_get_rcu(dev) \
44 ((struct net_device *)rcu_dereference(dev->rx_handler_data))
45
46struct pcpu_dstats {
47 u64 tx_pkts;
48 u64 tx_bytes;
49 u64 tx_drps;
50 u64 rx_pkts;
51 u64 rx_bytes;
52 struct u64_stats_sync syncp;
53};
54
55static struct dst_entry *vrf_ip_check(struct dst_entry *dst, u32 cookie)
56{
57 return dst;
58}
59
60static int vrf_ip_local_out(struct sk_buff *skb)
61{
62 return ip_local_out(skb);
63}
64
65static unsigned int vrf_v4_mtu(const struct dst_entry *dst)
66{
67 /* TO-DO: return max ethernet size? */
68 return dst->dev->mtu;
69}
70
71static void vrf_dst_destroy(struct dst_entry *dst)
72{
73 /* our dst lives forever - or until the device is closed */
74}
75
76static unsigned int vrf_default_advmss(const struct dst_entry *dst)
77{
78 return 65535 - 40;
79}
80
81static struct dst_ops vrf_dst_ops = {
82 .family = AF_INET,
83 .local_out = vrf_ip_local_out,
84 .check = vrf_ip_check,
85 .mtu = vrf_v4_mtu,
86 .destroy = vrf_dst_destroy,
87 .default_advmss = vrf_default_advmss,
88};
89
90static bool is_ip_rx_frame(struct sk_buff *skb)
91{
92 switch (skb->protocol) {
93 case htons(ETH_P_IP):
94 case htons(ETH_P_IPV6):
95 return true;
96 }
97 return false;
98}
99
100/* note: already called with rcu_read_lock */
101static rx_handler_result_t vrf_handle_frame(struct sk_buff **pskb)
102{
103 struct sk_buff *skb = *pskb;
104
105 if (is_ip_rx_frame(skb)) {
106 struct net_device *dev = vrf_master_get_rcu(skb->dev);
107 struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats);
108
109 u64_stats_update_begin(&dstats->syncp);
110 dstats->rx_pkts++;
111 dstats->rx_bytes += skb->len;
112 u64_stats_update_end(&dstats->syncp);
113
114 skb->dev = dev;
115
116 return RX_HANDLER_ANOTHER;
117 }
118 return RX_HANDLER_PASS;
119}
120
121static struct rtnl_link_stats64 *vrf_get_stats64(struct net_device *dev,
122 struct rtnl_link_stats64 *stats)
123{
124 int i;
125
126 for_each_possible_cpu(i) {
127 const struct pcpu_dstats *dstats;
128 u64 tbytes, tpkts, tdrops, rbytes, rpkts;
129 unsigned int start;
130
131 dstats = per_cpu_ptr(dev->dstats, i);
132 do {
133 start = u64_stats_fetch_begin_irq(&dstats->syncp);
134 tbytes = dstats->tx_bytes;
135 tpkts = dstats->tx_pkts;
136 tdrops = dstats->tx_drps;
137 rbytes = dstats->rx_bytes;
138 rpkts = dstats->rx_pkts;
139 } while (u64_stats_fetch_retry_irq(&dstats->syncp, start));
140 stats->tx_bytes += tbytes;
141 stats->tx_packets += tpkts;
142 stats->tx_dropped += tdrops;
143 stats->rx_bytes += rbytes;
144 stats->rx_packets += rpkts;
145 }
146 return stats;
147}
148
149static netdev_tx_t vrf_process_v6_outbound(struct sk_buff *skb,
150 struct net_device *dev)
151{
152 return 0;
153}
154
155static int vrf_send_v4_prep(struct sk_buff *skb, struct flowi4 *fl4,
156 struct net_device *vrf_dev)
157{
158 struct rtable *rt;
159 int err = 1;
160
161 rt = ip_route_output_flow(dev_net(vrf_dev), fl4, NULL);
162 if (IS_ERR(rt))
163 goto out;
164
165 /* TO-DO: what about broadcast ? */
166 if (rt->rt_type != RTN_UNICAST && rt->rt_type != RTN_LOCAL) {
167 ip_rt_put(rt);
168 goto out;
169 }
170
171 skb_dst_drop(skb);
172 skb_dst_set(skb, &rt->dst);
173 err = 0;
174out:
175 return err;
176}
177
178static netdev_tx_t vrf_process_v4_outbound(struct sk_buff *skb,
179 struct net_device *vrf_dev)
180{
181 struct iphdr *ip4h = ip_hdr(skb);
182 int ret = NET_XMIT_DROP;
183 struct flowi4 fl4 = {
184 /* needed to match OIF rule */
185 .flowi4_oif = vrf_dev->ifindex,
186 .flowi4_iif = LOOPBACK_IFINDEX,
187 .flowi4_tos = RT_TOS(ip4h->tos),
188 .flowi4_flags = FLOWI_FLAG_ANYSRC | FLOWI_FLAG_VRFSRC,
189 .daddr = ip4h->daddr,
190 };
191
192 if (vrf_send_v4_prep(skb, &fl4, vrf_dev))
193 goto err;
194
195 if (!ip4h->saddr) {
196 ip4h->saddr = inet_select_addr(skb_dst(skb)->dev, 0,
197 RT_SCOPE_LINK);
198 }
199
200 ret = ip_local_out(skb);
201 if (unlikely(net_xmit_eval(ret)))
202 vrf_dev->stats.tx_errors++;
203 else
204 ret = NET_XMIT_SUCCESS;
205
206out:
207 return ret;
208err:
209 vrf_dev->stats.tx_errors++;
210 kfree_skb(skb);
211 goto out;
212}
213
214static netdev_tx_t is_ip_tx_frame(struct sk_buff *skb, struct net_device *dev)
215{
216 switch (skb->protocol) {
217 case htons(ETH_P_IP):
218 return vrf_process_v4_outbound(skb, dev);
219 case htons(ETH_P_IPV6):
220 return vrf_process_v6_outbound(skb, dev);
221 default:
222 return NET_XMIT_DROP;
223 }
224}
225
226static netdev_tx_t vrf_xmit(struct sk_buff *skb, struct net_device *dev)
227{
228 netdev_tx_t ret = is_ip_tx_frame(skb, dev);
229
230 if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) {
231 struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats);
232
233 u64_stats_update_begin(&dstats->syncp);
234 dstats->tx_pkts++;
235 dstats->tx_bytes += skb->len;
236 u64_stats_update_end(&dstats->syncp);
237 } else {
238 this_cpu_inc(dev->dstats->tx_drps);
239 }
240
241 return ret;
242}
243
244static netdev_tx_t vrf_finish(struct sock *sk, struct sk_buff *skb)
245{
246 return dev_queue_xmit(skb);
247}
248
249static int vrf_output(struct sock *sk, struct sk_buff *skb)
250{
251 struct net_device *dev = skb_dst(skb)->dev;
252
253 IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUT, skb->len);
254
255 skb->dev = dev;
256 skb->protocol = htons(ETH_P_IP);
257
258 return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, sk, skb,
259 NULL, dev,
260 vrf_finish,
261 !(IPCB(skb)->flags & IPSKB_REROUTED));
262}
263
264static void vrf_rtable_destroy(struct net_vrf *vrf)
265{
266 struct dst_entry *dst = (struct dst_entry *)vrf->rth;
267
268 if (dst)
269 dst_destroy(dst);
270 vrf->rth = NULL;
271}
272
273static struct rtable *vrf_rtable_create(struct net_device *dev)
274{
275 struct rtable *rth;
276
277 rth = dst_alloc(&vrf_dst_ops, dev, 2,
278 DST_OBSOLETE_NONE,
279 (DST_HOST | DST_NOPOLICY | DST_NOXFRM));
280 if (rth) {
281 rth->dst.output = vrf_output;
282 rth->rt_genid = rt_genid_ipv4(dev_net(dev));
283 rth->rt_flags = 0;
284 rth->rt_type = RTN_UNICAST;
285 rth->rt_is_input = 0;
286 rth->rt_iif = 0;
287 rth->rt_pmtu = 0;
288 rth->rt_gateway = 0;
289 rth->rt_uses_gateway = 0;
290 INIT_LIST_HEAD(&rth->rt_uncached);
291 rth->rt_uncached_list = NULL;
292 rth->rt_lwtstate = NULL;
293 }
294
295 return rth;
296}
297
298/**************************** device handling ********************/
299
300/* cycle interface to flush neighbor cache and move routes across tables */
301static void cycle_netdev(struct net_device *dev)
302{
303 unsigned int flags = dev->flags;
304 int ret;
305
306 if (!netif_running(dev))
307 return;
308
309 ret = dev_change_flags(dev, flags & ~IFF_UP);
310 if (ret >= 0)
311 ret = dev_change_flags(dev, flags);
312
313 if (ret < 0) {
314 netdev_err(dev,
315 "Failed to cycle device %s; route tables might be wrong!\n",
316 dev->name);
317 }
318}
319
320static struct slave *__vrf_find_slave_dev(struct slave_queue *queue,
321 struct net_device *dev)
322{
323 struct list_head *head = &queue->all_slaves;
324 struct slave *slave;
325
326 list_for_each_entry(slave, head, list) {
327 if (slave->dev == dev)
328 return slave;
329 }
330
331 return NULL;
332}
333
334/* inverse of __vrf_insert_slave */
335static void __vrf_remove_slave(struct slave_queue *queue, struct slave *slave)
336{
337 dev_put(slave->dev);
338 list_del(&slave->list);
339 queue->num_slaves--;
340}
341
342static void __vrf_insert_slave(struct slave_queue *queue, struct slave *slave)
343{
344 dev_hold(slave->dev);
345 list_add(&slave->list, &queue->all_slaves);
346 queue->num_slaves++;
347}
348
349static int do_vrf_add_slave(struct net_device *dev, struct net_device *port_dev)
350{
351 struct net_vrf_dev *vrf_ptr = kmalloc(sizeof(*vrf_ptr), GFP_KERNEL);
352 struct slave *slave = kzalloc(sizeof(*slave), GFP_KERNEL);
353 struct slave *duplicate_slave;
354 struct net_vrf *vrf = netdev_priv(dev);
355 struct slave_queue *queue = &vrf->queue;
356 int ret = -ENOMEM;
357
358 if (!slave || !vrf_ptr)
359 goto out_fail;
360
361 slave->dev = port_dev;
362
363 vrf_ptr->ifindex = dev->ifindex;
364 vrf_ptr->tb_id = vrf->tb_id;
365
366 duplicate_slave = __vrf_find_slave_dev(queue, port_dev);
367 if (duplicate_slave) {
368 ret = -EBUSY;
369 goto out_fail;
370 }
371
372 __vrf_insert_slave(queue, slave);
373
374 /* register the packet handler for slave ports */
375 ret = netdev_rx_handler_register(port_dev, vrf_handle_frame, dev);
376 if (ret) {
377 netdev_err(port_dev,
378 "Device %s failed to register rx_handler\n",
379 port_dev->name);
380 goto out_remove;
381 }
382
383 ret = netdev_master_upper_dev_link(port_dev, dev);
384 if (ret < 0)
385 goto out_unregister;
386
387 port_dev->flags |= IFF_SLAVE;
388
389 rcu_assign_pointer(port_dev->vrf_ptr, vrf_ptr);
390 cycle_netdev(port_dev);
391
392 return 0;
393
394out_unregister:
395 netdev_rx_handler_unregister(port_dev);
396out_remove:
397 __vrf_remove_slave(queue, slave);
398out_fail:
399 kfree(vrf_ptr);
400 kfree(slave);
401 return ret;
402}
403
404static int vrf_add_slave(struct net_device *dev, struct net_device *port_dev)
405{
406 if (!netif_is_vrf(dev) || netif_is_vrf(port_dev) ||
407 vrf_is_slave(port_dev))
408 return -EINVAL;
409
410 return do_vrf_add_slave(dev, port_dev);
411}
412
413/* inverse of do_vrf_add_slave */
414static int do_vrf_del_slave(struct net_device *dev, struct net_device *port_dev)
415{
416 struct net_vrf_dev *vrf_ptr = rtnl_dereference(port_dev->vrf_ptr);
417 struct net_vrf *vrf = netdev_priv(dev);
418 struct slave_queue *queue = &vrf->queue;
419 struct slave *slave;
420
421 RCU_INIT_POINTER(port_dev->vrf_ptr, NULL);
422
423 netdev_upper_dev_unlink(port_dev, dev);
424 port_dev->flags &= ~IFF_SLAVE;
425
426 netdev_rx_handler_unregister(port_dev);
427
428 /* after netdev_rx_handler_unregister for synchronize_rcu */
429 kfree(vrf_ptr);
430
431 cycle_netdev(port_dev);
432
433 slave = __vrf_find_slave_dev(queue, port_dev);
434 if (slave)
435 __vrf_remove_slave(queue, slave);
436
437 kfree(slave);
438
439 return 0;
440}
441
442static int vrf_del_slave(struct net_device *dev, struct net_device *port_dev)
443{
444 if (!netif_is_vrf(dev))
445 return -EINVAL;
446
447 return do_vrf_del_slave(dev, port_dev);
448}
449
450static void vrf_dev_uninit(struct net_device *dev)
451{
452 struct net_vrf *vrf = netdev_priv(dev);
453 struct slave_queue *queue = &vrf->queue;
454 struct list_head *head = &queue->all_slaves;
455 struct slave *slave, *next;
456
457 vrf_rtable_destroy(vrf);
458
459 list_for_each_entry_safe(slave, next, head, list)
460 vrf_del_slave(dev, slave->dev);
461
462 if (dev->dstats)
463 free_percpu(dev->dstats);
464 dev->dstats = NULL;
465}
466
467static int vrf_dev_init(struct net_device *dev)
468{
469 struct net_vrf *vrf = netdev_priv(dev);
470
471 INIT_LIST_HEAD(&vrf->queue.all_slaves);
472
473 dev->dstats = netdev_alloc_pcpu_stats(struct pcpu_dstats);
474 if (!dev->dstats)
475 goto out_nomem;
476
477 /* create the default dst which points back to us */
478 vrf->rth = vrf_rtable_create(dev);
479 if (!vrf->rth)
480 goto out_stats;
481
482 dev->flags = IFF_MASTER | IFF_NOARP;
483
484 return 0;
485
486out_stats:
487 free_percpu(dev->dstats);
488 dev->dstats = NULL;
489out_nomem:
490 return -ENOMEM;
491}
492
493static const struct net_device_ops vrf_netdev_ops = {
494 .ndo_init = vrf_dev_init,
495 .ndo_uninit = vrf_dev_uninit,
496 .ndo_start_xmit = vrf_xmit,
497 .ndo_get_stats64 = vrf_get_stats64,
498 .ndo_add_slave = vrf_add_slave,
499 .ndo_del_slave = vrf_del_slave,
500};
501
502static void vrf_get_drvinfo(struct net_device *dev,
503 struct ethtool_drvinfo *info)
504{
505 strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
506 strlcpy(info->version, DRV_VERSION, sizeof(info->version));
507}
508
509static const struct ethtool_ops vrf_ethtool_ops = {
510 .get_drvinfo = vrf_get_drvinfo,
511};
512
513static void vrf_setup(struct net_device *dev)
514{
515 ether_setup(dev);
516
517 /* Initialize the device structure. */
518 dev->netdev_ops = &vrf_netdev_ops;
519 dev->ethtool_ops = &vrf_ethtool_ops;
520 dev->destructor = free_netdev;
521
522 /* Fill in device structure with ethernet-generic values. */
523 eth_hw_addr_random(dev);
524
525 /* don't acquire vrf device's netif_tx_lock when transmitting */
526 dev->features |= NETIF_F_LLTX;
527
528 /* don't allow vrf devices to change network namespaces. */
529 dev->features |= NETIF_F_NETNS_LOCAL;
530}
531
532static int vrf_validate(struct nlattr *tb[], struct nlattr *data[])
533{
534 if (tb[IFLA_ADDRESS]) {
535 if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
536 return -EINVAL;
537 if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
538 return -EADDRNOTAVAIL;
539 }
540 return 0;
541}
542
543static void vrf_dellink(struct net_device *dev, struct list_head *head)
544{
545 struct net_vrf_dev *vrf_ptr = rtnl_dereference(dev->vrf_ptr);
546
547 RCU_INIT_POINTER(dev->vrf_ptr, NULL);
548 kfree_rcu(vrf_ptr, rcu);
549 unregister_netdevice_queue(dev, head);
550}
551
552static int vrf_newlink(struct net *src_net, struct net_device *dev,
553 struct nlattr *tb[], struct nlattr *data[])
554{
555 struct net_vrf *vrf = netdev_priv(dev);
556 struct net_vrf_dev *vrf_ptr;
557 int err;
558
559 if (!data || !data[IFLA_VRF_TABLE])
560 return -EINVAL;
561
562 vrf->tb_id = nla_get_u32(data[IFLA_VRF_TABLE]);
563
564 dev->priv_flags |= IFF_VRF_MASTER;
565
566 err = -ENOMEM;
567 vrf_ptr = kmalloc(sizeof(*dev->vrf_ptr), GFP_KERNEL);
568 if (!vrf_ptr)
569 goto out_fail;
570
571 vrf_ptr->ifindex = dev->ifindex;
572 vrf_ptr->tb_id = vrf->tb_id;
573
574 err = register_netdevice(dev);
575 if (err < 0)
576 goto out_fail;
577
578 rcu_assign_pointer(dev->vrf_ptr, vrf_ptr);
579
580 return 0;
581
582out_fail:
583 kfree(vrf_ptr);
584 free_netdev(dev);
585 return err;
586}
587
588static size_t vrf_nl_getsize(const struct net_device *dev)
589{
590 return nla_total_size(sizeof(u32)); /* IFLA_VRF_TABLE */
591}
592
593static int vrf_fillinfo(struct sk_buff *skb,
594 const struct net_device *dev)
595{
596 struct net_vrf *vrf = netdev_priv(dev);
597
598 return nla_put_u32(skb, IFLA_VRF_TABLE, vrf->tb_id);
599}
600
601static const struct nla_policy vrf_nl_policy[IFLA_VRF_MAX + 1] = {
602 [IFLA_VRF_TABLE] = { .type = NLA_U32 },
603};
604
605static struct rtnl_link_ops vrf_link_ops __read_mostly = {
606 .kind = DRV_NAME,
607 .priv_size = sizeof(struct net_vrf),
608
609 .get_size = vrf_nl_getsize,
610 .policy = vrf_nl_policy,
611 .validate = vrf_validate,
612 .fill_info = vrf_fillinfo,
613
614 .newlink = vrf_newlink,
615 .dellink = vrf_dellink,
616 .setup = vrf_setup,
617 .maxtype = IFLA_VRF_MAX,
618};
619
620static int vrf_device_event(struct notifier_block *unused,
621 unsigned long event, void *ptr)
622{
623 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
624
625 /* only care about unregister events to drop slave references */
626 if (event == NETDEV_UNREGISTER) {
627 struct net_vrf_dev *vrf_ptr = rtnl_dereference(dev->vrf_ptr);
628 struct net_device *vrf_dev;
629
630 if (!vrf_ptr || netif_is_vrf(dev))
631 goto out;
632
633 vrf_dev = __dev_get_by_index(dev_net(dev), vrf_ptr->ifindex);
634 if (vrf_dev)
635 vrf_del_slave(vrf_dev, dev);
636 }
637out:
638 return NOTIFY_DONE;
639}
640
641static struct notifier_block vrf_notifier_block __read_mostly = {
642 .notifier_call = vrf_device_event,
643};
644
645static int __init vrf_init_module(void)
646{
647 int rc;
648
649 vrf_dst_ops.kmem_cachep =
650 kmem_cache_create("vrf_ip_dst_cache",
651 sizeof(struct rtable), 0,
652 SLAB_HWCACHE_ALIGN | SLAB_PANIC,
653 NULL);
654
655 if (!vrf_dst_ops.kmem_cachep)
656 return -ENOMEM;
657
658 register_netdevice_notifier(&vrf_notifier_block);
659
660 rc = rtnl_link_register(&vrf_link_ops);
661 if (rc < 0)
662 goto error;
663
664 return 0;
665
666error:
667 unregister_netdevice_notifier(&vrf_notifier_block);
668 kmem_cache_destroy(vrf_dst_ops.kmem_cachep);
669 return rc;
670}
671
672static void __exit vrf_cleanup_module(void)
673{
674 rtnl_link_unregister(&vrf_link_ops);
675 unregister_netdevice_notifier(&vrf_notifier_block);
676 kmem_cache_destroy(vrf_dst_ops.kmem_cachep);
677}
678
679module_init(vrf_init_module);
680module_exit(vrf_cleanup_module);
681MODULE_AUTHOR("Shrijeet Mukherjee, David Ahern");
682MODULE_DESCRIPTION("Device driver to instantiate VRF domains");
683MODULE_LICENSE("GPL");
684MODULE_ALIAS_RTNL_LINK(DRV_NAME);
685MODULE_VERSION(DRV_VERSION);