aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ip_vti.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/ip_vti.c')
-rw-r--r--net/ipv4/ip_vti.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c
index a917903d5e97..cc701fa70b12 100644
--- a/net/ipv4/ip_vti.c
+++ b/net/ipv4/ip_vti.c
@@ -557,6 +557,33 @@ static struct rtnl_link_ops vti_link_ops __read_mostly = {
557 .get_link_net = ip_tunnel_get_link_net, 557 .get_link_net = ip_tunnel_get_link_net,
558}; 558};
559 559
560static bool is_vti_tunnel(const struct net_device *dev)
561{
562 return dev->netdev_ops == &vti_netdev_ops;
563}
564
565static int vti_device_event(struct notifier_block *unused,
566 unsigned long event, void *ptr)
567{
568 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
569 struct ip_tunnel *tunnel = netdev_priv(dev);
570
571 if (!is_vti_tunnel(dev))
572 return NOTIFY_DONE;
573
574 switch (event) {
575 case NETDEV_DOWN:
576 if (!net_eq(tunnel->net, dev_net(dev)))
577 xfrm_garbage_collect(tunnel->net);
578 break;
579 }
580 return NOTIFY_DONE;
581}
582
583static struct notifier_block vti_notifier_block __read_mostly = {
584 .notifier_call = vti_device_event,
585};
586
560static int __init vti_init(void) 587static int __init vti_init(void)
561{ 588{
562 const char *msg; 589 const char *msg;
@@ -564,6 +591,8 @@ static int __init vti_init(void)
564 591
565 pr_info("IPv4 over IPsec tunneling driver\n"); 592 pr_info("IPv4 over IPsec tunneling driver\n");
566 593
594 register_netdevice_notifier(&vti_notifier_block);
595
567 msg = "tunnel device"; 596 msg = "tunnel device";
568 err = register_pernet_device(&vti_net_ops); 597 err = register_pernet_device(&vti_net_ops);
569 if (err < 0) 598 if (err < 0)
@@ -596,6 +625,7 @@ xfrm_proto_ah_failed:
596xfrm_proto_esp_failed: 625xfrm_proto_esp_failed:
597 unregister_pernet_device(&vti_net_ops); 626 unregister_pernet_device(&vti_net_ops);
598pernet_dev_failed: 627pernet_dev_failed:
628 unregister_netdevice_notifier(&vti_notifier_block);
599 pr_err("vti init: failed to register %s\n", msg); 629 pr_err("vti init: failed to register %s\n", msg);
600 return err; 630 return err;
601} 631}
@@ -607,6 +637,7 @@ static void __exit vti_fini(void)
607 xfrm4_protocol_deregister(&vti_ah4_protocol, IPPROTO_AH); 637 xfrm4_protocol_deregister(&vti_ah4_protocol, IPPROTO_AH);
608 xfrm4_protocol_deregister(&vti_esp4_protocol, IPPROTO_ESP); 638 xfrm4_protocol_deregister(&vti_esp4_protocol, IPPROTO_ESP);
609 unregister_pernet_device(&vti_net_ops); 639 unregister_pernet_device(&vti_net_ops);
640 unregister_netdevice_notifier(&vti_notifier_block);
610} 641}
611 642
612module_init(vti_init); 643module_init(vti_init);