diff options
author | Pavel Emelyanov <xemul@openvz.org> | 2008-04-16 04:04:13 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-04-16 04:04:13 -0400 |
commit | b9855c54dadc0768dcc3804df1972488783d2267 (patch) | |
tree | 37ef8c0d01725440d5b87205b538a555e7eff7d2 /net/ipv4/ipip.c | |
parent | 10dc4c7bb70533d16184aaaa69e137a7d2b9a3a8 (diff) |
[IPIP]: Make the fallback tunnel device per-net.
Create on in ipip_init_net(), use it all over the code (the
proper place to get the net from already exists) and destroy
in ipip_net_exit().
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/ipip.c')
-rw-r--r-- | net/ipv4/ipip.c | 67 |
1 files changed, 35 insertions, 32 deletions
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index e39a4c279a20..e657a6605e08 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c | |||
@@ -123,14 +123,13 @@ | |||
123 | 123 | ||
124 | static int ipip_net_id; | 124 | static int ipip_net_id; |
125 | struct ipip_net { | 125 | struct ipip_net { |
126 | struct net_device *fb_tunnel_dev; | ||
126 | }; | 127 | }; |
127 | 128 | ||
128 | static int ipip_fb_tunnel_init(struct net_device *dev); | 129 | static int ipip_fb_tunnel_init(struct net_device *dev); |
129 | static int ipip_tunnel_init(struct net_device *dev); | 130 | static int ipip_tunnel_init(struct net_device *dev); |
130 | static void ipip_tunnel_setup(struct net_device *dev); | 131 | static void ipip_tunnel_setup(struct net_device *dev); |
131 | 132 | ||
132 | static struct net_device *ipip_fb_tunnel_dev; | ||
133 | |||
134 | static struct ip_tunnel *tunnels_r_l[HASH_SIZE]; | 133 | static struct ip_tunnel *tunnels_r_l[HASH_SIZE]; |
135 | static struct ip_tunnel *tunnels_r[HASH_SIZE]; | 134 | static struct ip_tunnel *tunnels_r[HASH_SIZE]; |
136 | static struct ip_tunnel *tunnels_l[HASH_SIZE]; | 135 | static struct ip_tunnel *tunnels_l[HASH_SIZE]; |
@@ -257,7 +256,10 @@ failed_free: | |||
257 | 256 | ||
258 | static void ipip_tunnel_uninit(struct net_device *dev) | 257 | static void ipip_tunnel_uninit(struct net_device *dev) |
259 | { | 258 | { |
260 | if (dev == ipip_fb_tunnel_dev) { | 259 | struct net *net = dev_net(dev); |
260 | struct ipip_net *ipn = net_generic(net, ipip_net_id); | ||
261 | |||
262 | if (dev == ipn->fb_tunnel_dev) { | ||
261 | write_lock_bh(&ipip_lock); | 263 | write_lock_bh(&ipip_lock); |
262 | tunnels_wc[0] = NULL; | 264 | tunnels_wc[0] = NULL; |
263 | write_unlock_bh(&ipip_lock); | 265 | write_unlock_bh(&ipip_lock); |
@@ -693,11 +695,13 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) | |||
693 | int err = 0; | 695 | int err = 0; |
694 | struct ip_tunnel_parm p; | 696 | struct ip_tunnel_parm p; |
695 | struct ip_tunnel *t; | 697 | struct ip_tunnel *t; |
698 | struct net *net = dev_net(dev); | ||
699 | struct ipip_net *ipn = net_generic(net, ipip_net_id); | ||
696 | 700 | ||
697 | switch (cmd) { | 701 | switch (cmd) { |
698 | case SIOCGETTUNNEL: | 702 | case SIOCGETTUNNEL: |
699 | t = NULL; | 703 | t = NULL; |
700 | if (dev == ipip_fb_tunnel_dev) { | 704 | if (dev == ipn->fb_tunnel_dev) { |
701 | if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) { | 705 | if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) { |
702 | err = -EFAULT; | 706 | err = -EFAULT; |
703 | break; | 707 | break; |
@@ -730,7 +734,7 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) | |||
730 | 734 | ||
731 | t = ipip_tunnel_locate(&p, cmd == SIOCADDTUNNEL); | 735 | t = ipip_tunnel_locate(&p, cmd == SIOCADDTUNNEL); |
732 | 736 | ||
733 | if (dev != ipip_fb_tunnel_dev && cmd == SIOCCHGTUNNEL) { | 737 | if (dev != ipn->fb_tunnel_dev && cmd == SIOCCHGTUNNEL) { |
734 | if (t != NULL) { | 738 | if (t != NULL) { |
735 | if (t->dev != dev) { | 739 | if (t->dev != dev) { |
736 | err = -EEXIST; | 740 | err = -EEXIST; |
@@ -776,7 +780,7 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) | |||
776 | if (!capable(CAP_NET_ADMIN)) | 780 | if (!capable(CAP_NET_ADMIN)) |
777 | goto done; | 781 | goto done; |
778 | 782 | ||
779 | if (dev == ipip_fb_tunnel_dev) { | 783 | if (dev == ipn->fb_tunnel_dev) { |
780 | err = -EFAULT; | 784 | err = -EFAULT; |
781 | if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) | 785 | if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) |
782 | goto done; | 786 | goto done; |
@@ -784,7 +788,7 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) | |||
784 | if ((t = ipip_tunnel_locate(&p, 0)) == NULL) | 788 | if ((t = ipip_tunnel_locate(&p, 0)) == NULL) |
785 | goto done; | 789 | goto done; |
786 | err = -EPERM; | 790 | err = -EPERM; |
787 | if (t->dev == ipip_fb_tunnel_dev) | 791 | if (t->dev == ipn->fb_tunnel_dev) |
788 | goto done; | 792 | goto done; |
789 | dev = t->dev; | 793 | dev = t->dev; |
790 | } | 794 | } |
@@ -847,7 +851,7 @@ static int ipip_tunnel_init(struct net_device *dev) | |||
847 | return 0; | 851 | return 0; |
848 | } | 852 | } |
849 | 853 | ||
850 | static int __init ipip_fb_tunnel_init(struct net_device *dev) | 854 | static int ipip_fb_tunnel_init(struct net_device *dev) |
851 | { | 855 | { |
852 | struct ip_tunnel *tunnel = netdev_priv(dev); | 856 | struct ip_tunnel *tunnel = netdev_priv(dev); |
853 | struct iphdr *iph = &tunnel->parms.iph; | 857 | struct iphdr *iph = &tunnel->parms.iph; |
@@ -887,8 +891,26 @@ static int ipip_init_net(struct net *net) | |||
887 | if (err < 0) | 891 | if (err < 0) |
888 | goto err_assign; | 892 | goto err_assign; |
889 | 893 | ||
894 | ipn->fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel), | ||
895 | "tunl0", | ||
896 | ipip_tunnel_setup); | ||
897 | if (!ipn->fb_tunnel_dev) { | ||
898 | err = -ENOMEM; | ||
899 | goto err_alloc_dev; | ||
900 | } | ||
901 | |||
902 | ipn->fb_tunnel_dev->init = ipip_fb_tunnel_init; | ||
903 | dev_net_set(ipn->fb_tunnel_dev, net); | ||
904 | |||
905 | if ((err = register_netdev(ipn->fb_tunnel_dev))) | ||
906 | goto err_reg_dev; | ||
907 | |||
890 | return 0; | 908 | return 0; |
891 | 909 | ||
910 | err_reg_dev: | ||
911 | free_netdev(ipn->fb_tunnel_dev); | ||
912 | err_alloc_dev: | ||
913 | /* nothing */ | ||
892 | err_assign: | 914 | err_assign: |
893 | kfree(ipn); | 915 | kfree(ipn); |
894 | err_alloc: | 916 | err_alloc: |
@@ -900,6 +922,9 @@ static void ipip_exit_net(struct net *net) | |||
900 | struct ipip_net *ipn; | 922 | struct ipip_net *ipn; |
901 | 923 | ||
902 | ipn = net_generic(net, ipip_net_id); | 924 | ipn = net_generic(net, ipip_net_id); |
925 | rtnl_lock(); | ||
926 | unregister_netdevice(ipn->fb_tunnel_dev); | ||
927 | rtnl_unlock(); | ||
903 | kfree(ipn); | 928 | kfree(ipn); |
904 | } | 929 | } |
905 | 930 | ||
@@ -919,32 +944,11 @@ static int __init ipip_init(void) | |||
919 | return -EAGAIN; | 944 | return -EAGAIN; |
920 | } | 945 | } |
921 | 946 | ||
922 | ipip_fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel), | ||
923 | "tunl0", | ||
924 | ipip_tunnel_setup); | ||
925 | if (!ipip_fb_tunnel_dev) { | ||
926 | err = -ENOMEM; | ||
927 | goto err1; | ||
928 | } | ||
929 | |||
930 | ipip_fb_tunnel_dev->init = ipip_fb_tunnel_init; | ||
931 | |||
932 | if ((err = register_netdev(ipip_fb_tunnel_dev))) | ||
933 | goto err2; | ||
934 | |||
935 | err = register_pernet_gen_device(&ipip_net_id, &ipip_net_ops); | 947 | err = register_pernet_gen_device(&ipip_net_id, &ipip_net_ops); |
936 | if (err) | 948 | if (err) |
937 | goto err3; | 949 | xfrm4_tunnel_deregister(&ipip_handler, AF_INET); |
938 | out: | 950 | |
939 | return err; | 951 | return err; |
940 | err2: | ||
941 | free_netdev(ipip_fb_tunnel_dev); | ||
942 | err1: | ||
943 | xfrm4_tunnel_deregister(&ipip_handler, AF_INET); | ||
944 | goto out; | ||
945 | err3: | ||
946 | unregister_netdevice(ipip_fb_tunnel_dev); | ||
947 | goto err1; | ||
948 | } | 952 | } |
949 | 953 | ||
950 | static void __exit ipip_destroy_tunnels(void) | 954 | static void __exit ipip_destroy_tunnels(void) |
@@ -968,7 +972,6 @@ static void __exit ipip_fini(void) | |||
968 | 972 | ||
969 | rtnl_lock(); | 973 | rtnl_lock(); |
970 | ipip_destroy_tunnels(); | 974 | ipip_destroy_tunnels(); |
971 | unregister_netdevice(ipip_fb_tunnel_dev); | ||
972 | rtnl_unlock(); | 975 | rtnl_unlock(); |
973 | 976 | ||
974 | unregister_pernet_gen_device(ipip_net_id, &ipip_net_ops); | 977 | unregister_pernet_gen_device(ipip_net_id, &ipip_net_ops); |