diff options
Diffstat (limited to 'net/ipv4/ipip.c')
-rw-r--r-- | net/ipv4/ipip.c | 56 |
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 | ||
261 | failed: | 260 | failed: |
@@ -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 | ||
276 | static void ipip_err(struct sk_buff *skb, void *__unused) | 275 | static 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 | ||
855 | static struct xfrm_tunnel ipip_handler = { | 855 | static 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 | ||
860 | static inline int ipip_register(void) | ||
861 | { | ||
862 | return xfrm4_tunnel_register(&ipip_handler); | ||
863 | } | ||
864 | |||
865 | static inline int ipip_unregister(void) | ||
866 | { | ||
867 | return xfrm4_tunnel_deregister(&ipip_handler); | ||
868 | } | ||
869 | #else | ||
870 | static struct net_protocol ipip_protocol = { | ||
871 | .handler = ipip_rcv, | ||
872 | .err_handler = ipip_err, | ||
873 | .no_policy = 1, | ||
874 | }; | ||
875 | |||
876 | static inline int ipip_register(void) | ||
877 | { | ||
878 | return inet_add_protocol(&ipip_protocol, IPPROTO_IPIP); | ||
879 | } | ||
880 | |||
881 | static inline int ipip_unregister(void) | ||
882 | { | ||
883 | return inet_del_protocol(&ipip_protocol, IPPROTO_IPIP); | ||
884 | } | ||
885 | #endif | ||
886 | |||
860 | static char banner[] __initdata = | 887 | static 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 | ||
922 | static 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 | |||
895 | static void __exit ipip_fini(void) | 936 | static 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 | ||
903 | module_init(ipip_init); | 947 | module_init(ipip_init); |