aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@openvz.org>2008-04-16 04:16:18 -0400
committerDavid S. Miller <davem@davemloft.net>2008-04-16 04:16:18 -0400
commitcd3dbc194d6784624f21acbc622a75c92378ba5a (patch)
treed49e62d7ca620323d44579132a31bb23874a76ec
parentfcee5ec9fdd2b27bce2a6ae8cd8161ad9a8899df (diff)
[SIT]: Make the fallback tunnel device per-net
Allocate and register one in sit_init_net, use sitn->fb_tunnel_dev over the code and unregister one in sit_exit_net. Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/ipv6/sit.c61
1 files changed, 29 insertions, 32 deletions
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index e85ddcd763d0..d0c1f2db7f21 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -70,10 +70,9 @@ static void ipip6_tunnel_setup(struct net_device *dev);
70 70
71static int sit_net_id; 71static int sit_net_id;
72struct sit_net { 72struct sit_net {
73 struct net_device *fb_tunnel_dev;
73}; 74};
74 75
75static struct net_device *ipip6_fb_tunnel_dev;
76
77static struct ip_tunnel *tunnels_r_l[HASH_SIZE]; 76static struct ip_tunnel *tunnels_r_l[HASH_SIZE];
78static struct ip_tunnel *tunnels_r[HASH_SIZE]; 77static struct ip_tunnel *tunnels_r[HASH_SIZE];
79static struct ip_tunnel *tunnels_l[HASH_SIZE]; 78static struct ip_tunnel *tunnels_l[HASH_SIZE];
@@ -386,7 +385,7 @@ static void ipip6_tunnel_uninit(struct net_device *dev)
386 struct net *net = dev_net(dev); 385 struct net *net = dev_net(dev);
387 struct sit_net *sitn = net_generic(net, sit_net_id); 386 struct sit_net *sitn = net_generic(net, sit_net_id);
388 387
389 if (dev == ipip6_fb_tunnel_dev) { 388 if (dev == sitn->fb_tunnel_dev) {
390 write_lock_bh(&ipip6_lock); 389 write_lock_bh(&ipip6_lock);
391 tunnels_wc[0] = NULL; 390 tunnels_wc[0] = NULL;
392 write_unlock_bh(&ipip6_lock); 391 write_unlock_bh(&ipip6_lock);
@@ -862,7 +861,7 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
862 switch (cmd) { 861 switch (cmd) {
863 case SIOCGETTUNNEL: 862 case SIOCGETTUNNEL:
864 t = NULL; 863 t = NULL;
865 if (dev == ipip6_fb_tunnel_dev) { 864 if (dev == sitn->fb_tunnel_dev) {
866 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) { 865 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) {
867 err = -EFAULT; 866 err = -EFAULT;
868 break; 867 break;
@@ -895,7 +894,7 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
895 894
896 t = ipip6_tunnel_locate(net, &p, cmd == SIOCADDTUNNEL); 895 t = ipip6_tunnel_locate(net, &p, cmd == SIOCADDTUNNEL);
897 896
898 if (dev != ipip6_fb_tunnel_dev && cmd == SIOCCHGTUNNEL) { 897 if (dev != sitn->fb_tunnel_dev && cmd == SIOCCHGTUNNEL) {
899 if (t != NULL) { 898 if (t != NULL) {
900 if (t->dev != dev) { 899 if (t->dev != dev) {
901 err = -EEXIST; 900 err = -EEXIST;
@@ -940,7 +939,7 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
940 if (!capable(CAP_NET_ADMIN)) 939 if (!capable(CAP_NET_ADMIN))
941 goto done; 940 goto done;
942 941
943 if (dev == ipip6_fb_tunnel_dev) { 942 if (dev == sitn->fb_tunnel_dev) {
944 err = -EFAULT; 943 err = -EFAULT;
945 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) 944 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p)))
946 goto done; 945 goto done;
@@ -948,7 +947,7 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
948 if ((t = ipip6_tunnel_locate(net, &p, 0)) == NULL) 947 if ((t = ipip6_tunnel_locate(net, &p, 0)) == NULL)
949 goto done; 948 goto done;
950 err = -EPERM; 949 err = -EPERM;
951 if (t == netdev_priv(ipip6_fb_tunnel_dev)) 950 if (t == netdev_priv(sitn->fb_tunnel_dev))
952 goto done; 951 goto done;
953 dev = t->dev; 952 dev = t->dev;
954 } 953 }
@@ -964,7 +963,7 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
964 if (cmd != SIOCGETPRL && !capable(CAP_NET_ADMIN)) 963 if (cmd != SIOCGETPRL && !capable(CAP_NET_ADMIN))
965 goto done; 964 goto done;
966 err = -EINVAL; 965 err = -EINVAL;
967 if (dev == ipip6_fb_tunnel_dev) 966 if (dev == sitn->fb_tunnel_dev)
968 goto done; 967 goto done;
969 err = -EFAULT; 968 err = -EFAULT;
970 if (copy_from_user(&prl, ifr->ifr_ifru.ifru_data, sizeof(prl))) 969 if (copy_from_user(&prl, ifr->ifr_ifru.ifru_data, sizeof(prl)))
@@ -1047,7 +1046,7 @@ static int ipip6_tunnel_init(struct net_device *dev)
1047 return 0; 1046 return 0;
1048} 1047}
1049 1048
1050static int __init ipip6_fb_tunnel_init(struct net_device *dev) 1049static int ipip6_fb_tunnel_init(struct net_device *dev)
1051{ 1050{
1052 struct ip_tunnel *tunnel = netdev_priv(dev); 1051 struct ip_tunnel *tunnel = netdev_priv(dev);
1053 struct iphdr *iph = &tunnel->parms.iph; 1052 struct iphdr *iph = &tunnel->parms.iph;
@@ -1099,8 +1098,25 @@ static int sit_init_net(struct net *net)
1099 if (err < 0) 1098 if (err < 0)
1100 goto err_assign; 1099 goto err_assign;
1101 1100
1101 sitn->fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel), "sit0",
1102 ipip6_tunnel_setup);
1103 if (!sitn->fb_tunnel_dev) {
1104 err = -ENOMEM;
1105 goto err_alloc_dev;
1106 }
1107
1108 sitn->fb_tunnel_dev->init = ipip6_fb_tunnel_init;
1109 dev_net_set(sitn->fb_tunnel_dev, net);
1110
1111 if ((err = register_netdev(sitn->fb_tunnel_dev)))
1112 goto err_reg_dev;
1113
1102 return 0; 1114 return 0;
1103 1115
1116err_reg_dev:
1117 free_netdev(sitn->fb_tunnel_dev);
1118err_alloc_dev:
1119 /* nothing */
1104err_assign: 1120err_assign:
1105 kfree(sitn); 1121 kfree(sitn);
1106err_alloc: 1122err_alloc:
@@ -1112,6 +1128,9 @@ static void sit_exit_net(struct net *net)
1112 struct sit_net *sitn; 1128 struct sit_net *sitn;
1113 1129
1114 sitn = net_generic(net, sit_net_id); 1130 sitn = net_generic(net, sit_net_id);
1131 rtnl_lock();
1132 unregister_netdevice(sitn->fb_tunnel_dev);
1133 rtnl_unlock();
1115 kfree(sitn); 1134 kfree(sitn);
1116} 1135}
1117 1136
@@ -1126,7 +1145,6 @@ static void __exit sit_cleanup(void)
1126 1145
1127 rtnl_lock(); 1146 rtnl_lock();
1128 sit_destroy_tunnels(); 1147 sit_destroy_tunnels();
1129 unregister_netdevice(ipip6_fb_tunnel_dev);
1130 rtnl_unlock(); 1148 rtnl_unlock();
1131 1149
1132 unregister_pernet_gen_device(sit_net_id, &sit_net_ops); 1150 unregister_pernet_gen_device(sit_net_id, &sit_net_ops);
@@ -1143,32 +1161,11 @@ static int __init sit_init(void)
1143 return -EAGAIN; 1161 return -EAGAIN;
1144 } 1162 }
1145 1163
1146 ipip6_fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel), "sit0",
1147 ipip6_tunnel_setup);
1148 if (!ipip6_fb_tunnel_dev) {
1149 err = -ENOMEM;
1150 goto err1;
1151 }
1152
1153 ipip6_fb_tunnel_dev->init = ipip6_fb_tunnel_init;
1154
1155 if ((err = register_netdev(ipip6_fb_tunnel_dev)))
1156 goto err2;
1157
1158 err = register_pernet_gen_device(&sit_net_id, &sit_net_ops); 1164 err = register_pernet_gen_device(&sit_net_id, &sit_net_ops);
1159 if (err < 0) 1165 if (err < 0)
1160 goto err3; 1166 xfrm4_tunnel_deregister(&sit_handler, AF_INET6);
1161 1167
1162 out:
1163 return err; 1168 return err;
1164 err2:
1165 free_netdev(ipip6_fb_tunnel_dev);
1166 err1:
1167 xfrm4_tunnel_deregister(&sit_handler, AF_INET6);
1168 goto out;
1169err3:
1170 unregister_netdevice(ipip6_fb_tunnel_dev);
1171 goto err1;
1172} 1169}
1173 1170
1174module_init(sit_init); 1171module_init(sit_init);