aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/ip_tunnels.h2
-rw-r--r--net/ipv4/ip_gre.c4
-rw-r--r--net/ipv4/ip_tunnel.c43
-rw-r--r--net/ipv4/ip_vti.c2
-rw-r--r--net/ipv4/ipip.c3
5 files changed, 33 insertions, 21 deletions
diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
index c6acd9f8f877..5a76f2bef822 100644
--- a/include/net/ip_tunnels.h
+++ b/include/net/ip_tunnels.h
@@ -102,7 +102,7 @@ void ip_tunnel_dellink(struct net_device *dev, struct list_head *head);
102int ip_tunnel_init_net(struct net *net, int ip_tnl_net_id, 102int ip_tunnel_init_net(struct net *net, int ip_tnl_net_id,
103 struct rtnl_link_ops *ops, char *devname); 103 struct rtnl_link_ops *ops, char *devname);
104 104
105void ip_tunnel_delete_net(struct ip_tunnel_net *itn); 105void ip_tunnel_delete_net(struct ip_tunnel_net *itn, struct rtnl_link_ops *ops);
106 106
107void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, 107void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
108 const struct iphdr *tnl_params, const u8 protocol); 108 const struct iphdr *tnl_params, const u8 protocol);
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 1f6eab66f7ce..bc3a76521deb 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -534,7 +534,7 @@ static int __net_init ipgre_init_net(struct net *net)
534static void __net_exit ipgre_exit_net(struct net *net) 534static void __net_exit ipgre_exit_net(struct net *net)
535{ 535{
536 struct ip_tunnel_net *itn = net_generic(net, ipgre_net_id); 536 struct ip_tunnel_net *itn = net_generic(net, ipgre_net_id);
537 ip_tunnel_delete_net(itn); 537 ip_tunnel_delete_net(itn, &ipgre_link_ops);
538} 538}
539 539
540static struct pernet_operations ipgre_net_ops = { 540static struct pernet_operations ipgre_net_ops = {
@@ -767,7 +767,7 @@ static int __net_init ipgre_tap_init_net(struct net *net)
767static void __net_exit ipgre_tap_exit_net(struct net *net) 767static void __net_exit ipgre_tap_exit_net(struct net *net)
768{ 768{
769 struct ip_tunnel_net *itn = net_generic(net, gre_tap_net_id); 769 struct ip_tunnel_net *itn = net_generic(net, gre_tap_net_id);
770 ip_tunnel_delete_net(itn); 770 ip_tunnel_delete_net(itn, &ipgre_tap_ops);
771} 771}
772 772
773static struct pernet_operations ipgre_tap_net_ops = { 773static struct pernet_operations ipgre_tap_net_ops = {
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index a351a003ee6b..a4d9126c7b51 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -350,7 +350,7 @@ static int ip_tunnel_bind_dev(struct net_device *dev)
350 struct flowi4 fl4; 350 struct flowi4 fl4;
351 struct rtable *rt; 351 struct rtable *rt;
352 352
353 rt = ip_route_output_tunnel(dev_net(dev), &fl4, 353 rt = ip_route_output_tunnel(tunnel->net, &fl4,
354 tunnel->parms.iph.protocol, 354 tunnel->parms.iph.protocol,
355 iph->daddr, iph->saddr, 355 iph->daddr, iph->saddr,
356 tunnel->parms.o_key, 356 tunnel->parms.o_key,
@@ -365,7 +365,7 @@ static int ip_tunnel_bind_dev(struct net_device *dev)
365 } 365 }
366 366
367 if (!tdev && tunnel->parms.link) 367 if (!tdev && tunnel->parms.link)
368 tdev = __dev_get_by_index(dev_net(dev), tunnel->parms.link); 368 tdev = __dev_get_by_index(tunnel->net, tunnel->parms.link);
369 369
370 if (tdev) { 370 if (tdev) {
371 hlen = tdev->hard_header_len + tdev->needed_headroom; 371 hlen = tdev->hard_header_len + tdev->needed_headroom;
@@ -654,7 +654,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
654 } 654 }
655 } 655 }
656 656
657 err = iptunnel_xmit(dev_net(dev), rt, skb, 657 err = iptunnel_xmit(tunnel->net, rt, skb,
658 fl4.saddr, fl4.daddr, protocol, 658 fl4.saddr, fl4.daddr, protocol,
659 ip_tunnel_ecn_encap(tos, inner_iph, skb), ttl, df); 659 ip_tunnel_ecn_encap(tos, inner_iph, skb), ttl, df);
660 iptunnel_xmit_stats(err, &dev->stats, dev->tstats); 660 iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
@@ -821,11 +821,10 @@ static void ip_tunnel_dev_free(struct net_device *dev)
821 821
822void ip_tunnel_dellink(struct net_device *dev, struct list_head *head) 822void ip_tunnel_dellink(struct net_device *dev, struct list_head *head)
823{ 823{
824 struct net *net = dev_net(dev);
825 struct ip_tunnel *tunnel = netdev_priv(dev); 824 struct ip_tunnel *tunnel = netdev_priv(dev);
826 struct ip_tunnel_net *itn; 825 struct ip_tunnel_net *itn;
827 826
828 itn = net_generic(net, tunnel->ip_tnl_net_id); 827 itn = net_generic(tunnel->net, tunnel->ip_tnl_net_id);
829 828
830 if (itn->fb_tunnel_dev != dev) { 829 if (itn->fb_tunnel_dev != dev) {
831 ip_tunnel_del(netdev_priv(dev)); 830 ip_tunnel_del(netdev_priv(dev));
@@ -855,6 +854,10 @@ int ip_tunnel_init_net(struct net *net, int ip_tnl_net_id,
855 854
856 rtnl_lock(); 855 rtnl_lock();
857 itn->fb_tunnel_dev = __ip_tunnel_create(net, ops, &parms); 856 itn->fb_tunnel_dev = __ip_tunnel_create(net, ops, &parms);
857 /* FB netdevice is special: we have one, and only one per netns.
858 * Allowing to move it to another netns is clearly unsafe.
859 */
860 itn->fb_tunnel_dev->features |= NETIF_F_NETNS_LOCAL;
858 rtnl_unlock(); 861 rtnl_unlock();
859 862
860 if (IS_ERR(itn->fb_tunnel_dev)) 863 if (IS_ERR(itn->fb_tunnel_dev))
@@ -864,28 +867,39 @@ int ip_tunnel_init_net(struct net *net, int ip_tnl_net_id,
864} 867}
865EXPORT_SYMBOL_GPL(ip_tunnel_init_net); 868EXPORT_SYMBOL_GPL(ip_tunnel_init_net);
866 869
867static void ip_tunnel_destroy(struct ip_tunnel_net *itn, struct list_head *head) 870static void ip_tunnel_destroy(struct ip_tunnel_net *itn, struct list_head *head,
871 struct rtnl_link_ops *ops)
868{ 872{
873 struct net *net = dev_net(itn->fb_tunnel_dev);
874 struct net_device *dev, *aux;
869 int h; 875 int h;
870 876
877 for_each_netdev_safe(net, dev, aux)
878 if (dev->rtnl_link_ops == ops)
879 unregister_netdevice_queue(dev, head);
880
871 for (h = 0; h < IP_TNL_HASH_SIZE; h++) { 881 for (h = 0; h < IP_TNL_HASH_SIZE; h++) {
872 struct ip_tunnel *t; 882 struct ip_tunnel *t;
873 struct hlist_node *n; 883 struct hlist_node *n;
874 struct hlist_head *thead = &itn->tunnels[h]; 884 struct hlist_head *thead = &itn->tunnels[h];
875 885
876 hlist_for_each_entry_safe(t, n, thead, hash_node) 886 hlist_for_each_entry_safe(t, n, thead, hash_node)
877 unregister_netdevice_queue(t->dev, head); 887 /* If dev is in the same netns, it has already
888 * been added to the list by the previous loop.
889 */
890 if (!net_eq(dev_net(t->dev), net))
891 unregister_netdevice_queue(t->dev, head);
878 } 892 }
879 if (itn->fb_tunnel_dev) 893 if (itn->fb_tunnel_dev)
880 unregister_netdevice_queue(itn->fb_tunnel_dev, head); 894 unregister_netdevice_queue(itn->fb_tunnel_dev, head);
881} 895}
882 896
883void ip_tunnel_delete_net(struct ip_tunnel_net *itn) 897void ip_tunnel_delete_net(struct ip_tunnel_net *itn, struct rtnl_link_ops *ops)
884{ 898{
885 LIST_HEAD(list); 899 LIST_HEAD(list);
886 900
887 rtnl_lock(); 901 rtnl_lock();
888 ip_tunnel_destroy(itn, &list); 902 ip_tunnel_destroy(itn, &list, ops);
889 unregister_netdevice_many(&list); 903 unregister_netdevice_many(&list);
890 rtnl_unlock(); 904 rtnl_unlock();
891} 905}
@@ -929,23 +943,21 @@ EXPORT_SYMBOL_GPL(ip_tunnel_newlink);
929int ip_tunnel_changelink(struct net_device *dev, struct nlattr *tb[], 943int ip_tunnel_changelink(struct net_device *dev, struct nlattr *tb[],
930 struct ip_tunnel_parm *p) 944 struct ip_tunnel_parm *p)
931{ 945{
932 struct ip_tunnel *t, *nt; 946 struct ip_tunnel *t;
933 struct net *net = dev_net(dev);
934 struct ip_tunnel *tunnel = netdev_priv(dev); 947 struct ip_tunnel *tunnel = netdev_priv(dev);
948 struct net *net = tunnel->net;
935 struct ip_tunnel_net *itn = net_generic(net, tunnel->ip_tnl_net_id); 949 struct ip_tunnel_net *itn = net_generic(net, tunnel->ip_tnl_net_id);
936 950
937 if (dev == itn->fb_tunnel_dev) 951 if (dev == itn->fb_tunnel_dev)
938 return -EINVAL; 952 return -EINVAL;
939 953
940 nt = netdev_priv(dev);
941
942 t = ip_tunnel_find(itn, p, dev->type); 954 t = ip_tunnel_find(itn, p, dev->type);
943 955
944 if (t) { 956 if (t) {
945 if (t->dev != dev) 957 if (t->dev != dev)
946 return -EEXIST; 958 return -EEXIST;
947 } else { 959 } else {
948 t = nt; 960 t = tunnel;
949 961
950 if (dev->type != ARPHRD_ETHER) { 962 if (dev->type != ARPHRD_ETHER) {
951 unsigned int nflags = 0; 963 unsigned int nflags = 0;
@@ -984,6 +996,7 @@ int ip_tunnel_init(struct net_device *dev)
984 } 996 }
985 997
986 tunnel->dev = dev; 998 tunnel->dev = dev;
999 tunnel->net = dev_net(dev);
987 strcpy(tunnel->parms.name, dev->name); 1000 strcpy(tunnel->parms.name, dev->name);
988 iph->version = 4; 1001 iph->version = 4;
989 iph->ihl = 5; 1002 iph->ihl = 5;
@@ -994,8 +1007,8 @@ EXPORT_SYMBOL_GPL(ip_tunnel_init);
994 1007
995void ip_tunnel_uninit(struct net_device *dev) 1008void ip_tunnel_uninit(struct net_device *dev)
996{ 1009{
997 struct net *net = dev_net(dev);
998 struct ip_tunnel *tunnel = netdev_priv(dev); 1010 struct ip_tunnel *tunnel = netdev_priv(dev);
1011 struct net *net = tunnel->net;
999 struct ip_tunnel_net *itn; 1012 struct ip_tunnel_net *itn;
1000 1013
1001 itn = net_generic(net, tunnel->ip_tnl_net_id); 1014 itn = net_generic(net, tunnel->ip_tnl_net_id);
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c
index 79b263da4168..e805e7b3030e 100644
--- a/net/ipv4/ip_vti.c
+++ b/net/ipv4/ip_vti.c
@@ -318,7 +318,7 @@ static int __net_init vti_init_net(struct net *net)
318static void __net_exit vti_exit_net(struct net *net) 318static void __net_exit vti_exit_net(struct net *net)
319{ 319{
320 struct ip_tunnel_net *itn = net_generic(net, vti_net_id); 320 struct ip_tunnel_net *itn = net_generic(net, vti_net_id);
321 ip_tunnel_delete_net(itn); 321 ip_tunnel_delete_net(itn, &vti_link_ops);
322} 322}
323 323
324static struct pernet_operations vti_net_ops = { 324static struct pernet_operations vti_net_ops = {
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 51fc2a1dcdd3..87bd2952c733 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -286,7 +286,6 @@ static void ipip_tunnel_setup(struct net_device *dev)
286 dev->flags = IFF_NOARP; 286 dev->flags = IFF_NOARP;
287 dev->iflink = 0; 287 dev->iflink = 0;
288 dev->addr_len = 4; 288 dev->addr_len = 4;
289 dev->features |= NETIF_F_NETNS_LOCAL;
290 dev->features |= NETIF_F_LLTX; 289 dev->features |= NETIF_F_LLTX;
291 dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; 290 dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
292 291
@@ -437,7 +436,7 @@ static int __net_init ipip_init_net(struct net *net)
437static void __net_exit ipip_exit_net(struct net *net) 436static void __net_exit ipip_exit_net(struct net *net)
438{ 437{
439 struct ip_tunnel_net *itn = net_generic(net, ipip_net_id); 438 struct ip_tunnel_net *itn = net_generic(net, ipip_net_id);
440 ip_tunnel_delete_net(itn); 439 ip_tunnel_delete_net(itn, &ipip_link_ops);
441} 440}
442 441
443static struct pernet_operations ipip_net_ops = { 442static struct pernet_operations ipip_net_ops = {