aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ipip.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/ipip.c')
-rw-r--r--net/ipv4/ipip.c56
1 files changed, 50 insertions, 6 deletions
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 68a78731f722..c05c1df0bb04 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -255,7 +255,6 @@ static struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int c
255 255
256 dev_hold(dev); 256 dev_hold(dev);
257 ipip_tunnel_link(nt); 257 ipip_tunnel_link(nt);
258 /* Do not decrement MOD_USE_COUNT here. */
259 return nt; 258 return nt;
260 259
261failed: 260failed:
@@ -273,7 +272,7 @@ static void ipip_tunnel_uninit(struct net_device *dev)
273 dev_put(dev); 272 dev_put(dev);
274} 273}
275 274
276static void ipip_err(struct sk_buff *skb, void *__unused) 275static void ipip_err(struct sk_buff *skb, u32 info)
277{ 276{
278#ifndef I_WISH_WORLD_WERE_PERFECT 277#ifndef I_WISH_WORLD_WERE_PERFECT
279 278
@@ -852,11 +851,39 @@ static int __init ipip_fb_tunnel_init(struct net_device *dev)
852 return 0; 851 return 0;
853} 852}
854 853
854#ifdef CONFIG_INET_TUNNEL
855static struct xfrm_tunnel ipip_handler = { 855static struct xfrm_tunnel ipip_handler = {
856 .handler = ipip_rcv, 856 .handler = ipip_rcv,
857 .err_handler = ipip_err, 857 .err_handler = ipip_err,
858}; 858};
859 859
860static inline int ipip_register(void)
861{
862 return xfrm4_tunnel_register(&ipip_handler);
863}
864
865static inline int ipip_unregister(void)
866{
867 return xfrm4_tunnel_deregister(&ipip_handler);
868}
869#else
870static struct net_protocol ipip_protocol = {
871 .handler = ipip_rcv,
872 .err_handler = ipip_err,
873 .no_policy = 1,
874};
875
876static inline int ipip_register(void)
877{
878 return inet_add_protocol(&ipip_protocol, IPPROTO_IPIP);
879}
880
881static inline int ipip_unregister(void)
882{
883 return inet_del_protocol(&ipip_protocol, IPPROTO_IPIP);
884}
885#endif
886
860static char banner[] __initdata = 887static char banner[] __initdata =
861 KERN_INFO "IPv4 over IPv4 tunneling driver\n"; 888 KERN_INFO "IPv4 over IPv4 tunneling driver\n";
862 889
@@ -866,7 +893,7 @@ static int __init ipip_init(void)
866 893
867 printk(banner); 894 printk(banner);
868 895
869 if (xfrm4_tunnel_register(&ipip_handler) < 0) { 896 if (ipip_register() < 0) {
870 printk(KERN_INFO "ipip init: can't register tunnel\n"); 897 printk(KERN_INFO "ipip init: can't register tunnel\n");
871 return -EAGAIN; 898 return -EAGAIN;
872 } 899 }
@@ -888,16 +915,33 @@ static int __init ipip_init(void)
888 err2: 915 err2:
889 free_netdev(ipip_fb_tunnel_dev); 916 free_netdev(ipip_fb_tunnel_dev);
890 err1: 917 err1:
891 xfrm4_tunnel_deregister(&ipip_handler); 918 ipip_unregister();
892 goto out; 919 goto out;
893} 920}
894 921
922static void __exit ipip_destroy_tunnels(void)
923{
924 int prio;
925
926 for (prio = 1; prio < 4; prio++) {
927 int h;
928 for (h = 0; h < HASH_SIZE; h++) {
929 struct ip_tunnel *t;
930 while ((t = tunnels[prio][h]) != NULL)
931 unregister_netdevice(t->dev);
932 }
933 }
934}
935
895static void __exit ipip_fini(void) 936static void __exit ipip_fini(void)
896{ 937{
897 if (xfrm4_tunnel_deregister(&ipip_handler) < 0) 938 if (ipip_unregister() < 0)
898 printk(KERN_INFO "ipip close: can't deregister tunnel\n"); 939 printk(KERN_INFO "ipip close: can't deregister tunnel\n");
899 940
900 unregister_netdev(ipip_fb_tunnel_dev); 941 rtnl_lock();
942 ipip_destroy_tunnels();
943 unregister_netdevice(ipip_fb_tunnel_dev);
944 rtnl_unlock();
901} 945}
902 946
903module_init(ipip_init); 947module_init(ipip_init);