aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ip6_tunnel.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/ip6_tunnel.c')
-rw-r--r--net/ipv6/ip6_tunnel.c48
1 files changed, 24 insertions, 24 deletions
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 72485a3ac9fd..511a6c416887 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -82,12 +82,10 @@ static void ip6_tnl_dev_setup(struct net_device *dev);
82 82
83static int ip6_tnl_net_id; 83static int ip6_tnl_net_id;
84struct ip6_tnl_net { 84struct ip6_tnl_net {
85 /* the IPv6 tunnel fallback device */
86 struct net_device *fb_tnl_dev;
85}; 87};
86 88
87/* the IPv6 tunnel fallback device */
88static struct net_device *ip6_fb_tnl_dev;
89
90
91/* lists for storing tunnels in use */ 89/* lists for storing tunnels in use */
92static struct ip6_tnl *tnls_r_l[HASH_SIZE]; 90static struct ip6_tnl *tnls_r_l[HASH_SIZE];
93static struct ip6_tnl *tnls_wc[1]; 91static struct ip6_tnl *tnls_wc[1];
@@ -314,7 +312,7 @@ ip6_tnl_dev_uninit(struct net_device *dev)
314 struct net *net = dev_net(dev); 312 struct net *net = dev_net(dev);
315 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); 313 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
316 314
317 if (dev == ip6_fb_tnl_dev) { 315 if (dev == ip6n->fb_tnl_dev) {
318 write_lock_bh(&ip6_tnl_lock); 316 write_lock_bh(&ip6_tnl_lock);
319 tnls_wc[0] = NULL; 317 tnls_wc[0] = NULL;
320 write_unlock_bh(&ip6_tnl_lock); 318 write_unlock_bh(&ip6_tnl_lock);
@@ -1209,7 +1207,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1209 1207
1210 switch (cmd) { 1208 switch (cmd) {
1211 case SIOCGETTUNNEL: 1209 case SIOCGETTUNNEL:
1212 if (dev == ip6_fb_tnl_dev) { 1210 if (dev == ip6n->fb_tnl_dev) {
1213 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof (p))) { 1211 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof (p))) {
1214 err = -EFAULT; 1212 err = -EFAULT;
1215 break; 1213 break;
@@ -1236,7 +1234,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1236 p.proto != 0) 1234 p.proto != 0)
1237 break; 1235 break;
1238 t = ip6_tnl_locate(net, &p, cmd == SIOCADDTUNNEL); 1236 t = ip6_tnl_locate(net, &p, cmd == SIOCADDTUNNEL);
1239 if (dev != ip6_fb_tnl_dev && cmd == SIOCCHGTUNNEL) { 1237 if (dev != ip6n->fb_tnl_dev && cmd == SIOCCHGTUNNEL) {
1240 if (t != NULL) { 1238 if (t != NULL) {
1241 if (t->dev != dev) { 1239 if (t->dev != dev) {
1242 err = -EEXIST; 1240 err = -EEXIST;
@@ -1263,7 +1261,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1263 if (!capable(CAP_NET_ADMIN)) 1261 if (!capable(CAP_NET_ADMIN))
1264 break; 1262 break;
1265 1263
1266 if (dev == ip6_fb_tnl_dev) { 1264 if (dev == ip6n->fb_tnl_dev) {
1267 err = -EFAULT; 1265 err = -EFAULT;
1268 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof (p))) 1266 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof (p)))
1269 break; 1267 break;
@@ -1271,7 +1269,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1271 if ((t = ip6_tnl_locate(net, &p, 0)) == NULL) 1269 if ((t = ip6_tnl_locate(net, &p, 0)) == NULL)
1272 break; 1270 break;
1273 err = -EPERM; 1271 err = -EPERM;
1274 if (t->dev == ip6_fb_tnl_dev) 1272 if (t->dev == ip6n->fb_tnl_dev)
1275 break; 1273 break;
1276 dev = t->dev; 1274 dev = t->dev;
1277 } 1275 }
@@ -1413,8 +1411,25 @@ static int ip6_tnl_init_net(struct net *net)
1413 if (err < 0) 1411 if (err < 0)
1414 goto err_assign; 1412 goto err_assign;
1415 1413
1414 err = -ENOMEM;
1415 ip6n->fb_tnl_dev = alloc_netdev(sizeof(struct ip6_tnl), "ip6tnl0",
1416 ip6_tnl_dev_setup);
1417
1418 if (!ip6n->fb_tnl_dev)
1419 goto err_alloc_dev;
1420
1421 ip6n->fb_tnl_dev->init = ip6_fb_tnl_dev_init;
1422 dev_net_set(ip6n->fb_tnl_dev, net);
1423
1424 err = register_netdev(ip6n->fb_tnl_dev);
1425 if (err < 0)
1426 goto err_register;
1416 return 0; 1427 return 0;
1417 1428
1429err_register:
1430 free_netdev(ip6n->fb_tnl_dev);
1431err_alloc_dev:
1432 /* nothing */
1418err_assign: 1433err_assign:
1419 kfree(ip6n); 1434 kfree(ip6n);
1420err_alloc: 1435err_alloc:
@@ -1455,27 +1470,12 @@ static int __init ip6_tunnel_init(void)
1455 err = -EAGAIN; 1470 err = -EAGAIN;
1456 goto unreg_ip4ip6; 1471 goto unreg_ip4ip6;
1457 } 1472 }
1458 ip6_fb_tnl_dev = alloc_netdev(sizeof(struct ip6_tnl), "ip6tnl0",
1459 ip6_tnl_dev_setup);
1460
1461 if (!ip6_fb_tnl_dev) {
1462 err = -ENOMEM;
1463 goto fail;
1464 }
1465 ip6_fb_tnl_dev->init = ip6_fb_tnl_dev_init;
1466
1467 if ((err = register_netdev(ip6_fb_tnl_dev))) {
1468 free_netdev(ip6_fb_tnl_dev);
1469 goto fail;
1470 }
1471 1473
1472 err = register_pernet_gen_device(&ip6_tnl_net_id, &ip6_tnl_net_ops); 1474 err = register_pernet_gen_device(&ip6_tnl_net_id, &ip6_tnl_net_ops);
1473 if (err < 0) 1475 if (err < 0)
1474 goto err_pernet; 1476 goto err_pernet;
1475 return 0; 1477 return 0;
1476err_pernet: 1478err_pernet:
1477 unregister_netdevice(ip6_fb_tnl_dev);
1478fail:
1479 xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6); 1479 xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6);
1480unreg_ip4ip6: 1480unreg_ip4ip6:
1481 xfrm6_tunnel_deregister(&ip4ip6_handler, AF_INET); 1481 xfrm6_tunnel_deregister(&ip4ip6_handler, AF_INET);