aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorNicolas Dichtel <nicolas.dichtel@6wind.com>2013-08-13 11:51:12 -0400
committerDavid S. Miller <davem@davemloft.net>2013-08-15 04:00:20 -0400
commit0bd8762824e73a3cce7b7560a97463301764b616 (patch)
tree1de2d9f01b9947e87705c7d00082fa474e517c5f /net/ipv6
parent6c742e714d8c282fd8f8b22d3e20b5141738c1ee (diff)
ip6tnl: add x-netns support
This patch allows to switch the netns when packet is encapsulated or decapsulated. In other word, the encapsulated packet is received in a netns, where the lookup is done to find the tunnel. Once the tunnel is found, the packet is decapsulated and injecting into the corresponding interface which stands to another netns. When one of the two netns is removed, the tunnel is destroyed. Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/ip6_gre.c5
-rw-r--r--net/ipv6/ip6_tunnel.c41
2 files changed, 36 insertions, 10 deletions
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index ecd60733e5e2..f2d0a42f8057 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -335,6 +335,7 @@ static struct ip6_tnl *ip6gre_tunnel_locate(struct net *net,
335 dev->rtnl_link_ops = &ip6gre_link_ops; 335 dev->rtnl_link_ops = &ip6gre_link_ops;
336 336
337 nt->dev = dev; 337 nt->dev = dev;
338 nt->net = dev_net(dev);
338 ip6gre_tnl_link_config(nt, 1); 339 ip6gre_tnl_link_config(nt, 1);
339 340
340 if (register_netdevice(dev) < 0) 341 if (register_netdevice(dev) < 0)
@@ -1255,6 +1256,7 @@ static int ip6gre_tunnel_init(struct net_device *dev)
1255 tunnel = netdev_priv(dev); 1256 tunnel = netdev_priv(dev);
1256 1257
1257 tunnel->dev = dev; 1258 tunnel->dev = dev;
1259 tunnel->net = dev_net(dev);
1258 strcpy(tunnel->parms.name, dev->name); 1260 strcpy(tunnel->parms.name, dev->name);
1259 1261
1260 memcpy(dev->dev_addr, &tunnel->parms.laddr, sizeof(struct in6_addr)); 1262 memcpy(dev->dev_addr, &tunnel->parms.laddr, sizeof(struct in6_addr));
@@ -1275,6 +1277,7 @@ static void ip6gre_fb_tunnel_init(struct net_device *dev)
1275 struct ip6_tnl *tunnel = netdev_priv(dev); 1277 struct ip6_tnl *tunnel = netdev_priv(dev);
1276 1278
1277 tunnel->dev = dev; 1279 tunnel->dev = dev;
1280 tunnel->net = dev_net(dev);
1278 strcpy(tunnel->parms.name, dev->name); 1281 strcpy(tunnel->parms.name, dev->name);
1279 1282
1280 tunnel->hlen = sizeof(struct ipv6hdr) + 4; 1283 tunnel->hlen = sizeof(struct ipv6hdr) + 4;
@@ -1450,6 +1453,7 @@ static int ip6gre_tap_init(struct net_device *dev)
1450 tunnel = netdev_priv(dev); 1453 tunnel = netdev_priv(dev);
1451 1454
1452 tunnel->dev = dev; 1455 tunnel->dev = dev;
1456 tunnel->net = dev_net(dev);
1453 strcpy(tunnel->parms.name, dev->name); 1457 strcpy(tunnel->parms.name, dev->name);
1454 1458
1455 ip6gre_tnl_link_config(tunnel, 1); 1459 ip6gre_tnl_link_config(tunnel, 1);
@@ -1501,6 +1505,7 @@ static int ip6gre_newlink(struct net *src_net, struct net_device *dev,
1501 eth_hw_addr_random(dev); 1505 eth_hw_addr_random(dev);
1502 1506
1503 nt->dev = dev; 1507 nt->dev = dev;
1508 nt->net = dev_net(dev);
1504 ip6gre_tnl_link_config(nt, !tb[IFLA_MTU]); 1509 ip6gre_tnl_link_config(nt, !tb[IFLA_MTU]);
1505 1510
1506 /* Can use a lockless transmit, unless we generate output sequences */ 1511 /* Can use a lockless transmit, unless we generate output sequences */
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 1e55866cead7..cc3bb201b8b0 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -315,6 +315,7 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct __ip6_tnl_parm *p)
315 315
316 t = netdev_priv(dev); 316 t = netdev_priv(dev);
317 t->parms = *p; 317 t->parms = *p;
318 t->net = dev_net(dev);
318 err = ip6_tnl_create2(dev); 319 err = ip6_tnl_create2(dev);
319 if (err < 0) 320 if (err < 0)
320 goto failed_free; 321 goto failed_free;
@@ -374,7 +375,7 @@ static void
374ip6_tnl_dev_uninit(struct net_device *dev) 375ip6_tnl_dev_uninit(struct net_device *dev)
375{ 376{
376 struct ip6_tnl *t = netdev_priv(dev); 377 struct ip6_tnl *t = netdev_priv(dev);
377 struct net *net = dev_net(dev); 378 struct net *net = t->net;
378 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); 379 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
379 380
380 if (dev == ip6n->fb_tnl_dev) 381 if (dev == ip6n->fb_tnl_dev)
@@ -741,7 +742,7 @@ int ip6_tnl_rcv_ctl(struct ip6_tnl *t,
741{ 742{
742 struct __ip6_tnl_parm *p = &t->parms; 743 struct __ip6_tnl_parm *p = &t->parms;
743 int ret = 0; 744 int ret = 0;
744 struct net *net = dev_net(t->dev); 745 struct net *net = t->net;
745 746
746 if ((p->flags & IP6_TNL_F_CAP_RCV) || 747 if ((p->flags & IP6_TNL_F_CAP_RCV) ||
747 ((p->flags & IP6_TNL_F_CAP_PER_PACKET) && 748 ((p->flags & IP6_TNL_F_CAP_PER_PACKET) &&
@@ -827,6 +828,9 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol,
827 tstats->rx_packets++; 828 tstats->rx_packets++;
828 tstats->rx_bytes += skb->len; 829 tstats->rx_bytes += skb->len;
829 830
831 if (!net_eq(t->net, dev_net(t->dev)))
832 skb_scrub_packet(skb);
833
830 netif_rx(skb); 834 netif_rx(skb);
831 835
832 rcu_read_unlock(); 836 rcu_read_unlock();
@@ -895,7 +899,7 @@ int ip6_tnl_xmit_ctl(struct ip6_tnl *t)
895{ 899{
896 struct __ip6_tnl_parm *p = &t->parms; 900 struct __ip6_tnl_parm *p = &t->parms;
897 int ret = 0; 901 int ret = 0;
898 struct net *net = dev_net(t->dev); 902 struct net *net = t->net;
899 903
900 if (p->flags & IP6_TNL_F_CAP_XMIT) { 904 if (p->flags & IP6_TNL_F_CAP_XMIT) {
901 struct net_device *ldev = NULL; 905 struct net_device *ldev = NULL;
@@ -945,8 +949,8 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
945 int encap_limit, 949 int encap_limit,
946 __u32 *pmtu) 950 __u32 *pmtu)
947{ 951{
948 struct net *net = dev_net(dev);
949 struct ip6_tnl *t = netdev_priv(dev); 952 struct ip6_tnl *t = netdev_priv(dev);
953 struct net *net = t->net;
950 struct net_device_stats *stats = &t->dev->stats; 954 struct net_device_stats *stats = &t->dev->stats;
951 struct ipv6hdr *ipv6h = ipv6_hdr(skb); 955 struct ipv6hdr *ipv6h = ipv6_hdr(skb);
952 struct ipv6_tel_txoption opt; 956 struct ipv6_tel_txoption opt;
@@ -996,6 +1000,9 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
996 goto tx_err_dst_release; 1000 goto tx_err_dst_release;
997 } 1001 }
998 1002
1003 if (!net_eq(t->net, dev_net(dev)))
1004 skb_scrub_packet(skb);
1005
999 /* 1006 /*
1000 * Okay, now see if we can stuff it in the buffer as-is. 1007 * Okay, now see if we can stuff it in the buffer as-is.
1001 */ 1008 */
@@ -1202,7 +1209,7 @@ static void ip6_tnl_link_config(struct ip6_tnl *t)
1202 int strict = (ipv6_addr_type(&p->raddr) & 1209 int strict = (ipv6_addr_type(&p->raddr) &
1203 (IPV6_ADDR_MULTICAST|IPV6_ADDR_LINKLOCAL)); 1210 (IPV6_ADDR_MULTICAST|IPV6_ADDR_LINKLOCAL));
1204 1211
1205 struct rt6_info *rt = rt6_lookup(dev_net(dev), 1212 struct rt6_info *rt = rt6_lookup(t->net,
1206 &p->raddr, &p->laddr, 1213 &p->raddr, &p->laddr,
1207 p->link, strict); 1214 p->link, strict);
1208 1215
@@ -1251,7 +1258,7 @@ ip6_tnl_change(struct ip6_tnl *t, const struct __ip6_tnl_parm *p)
1251 1258
1252static int ip6_tnl_update(struct ip6_tnl *t, struct __ip6_tnl_parm *p) 1259static int ip6_tnl_update(struct ip6_tnl *t, struct __ip6_tnl_parm *p)
1253{ 1260{
1254 struct net *net = dev_net(t->dev); 1261 struct net *net = t->net;
1255 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); 1262 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
1256 int err; 1263 int err;
1257 1264
@@ -1463,7 +1470,6 @@ static void ip6_tnl_dev_setup(struct net_device *dev)
1463 dev->mtu-=8; 1470 dev->mtu-=8;
1464 dev->flags |= IFF_NOARP; 1471 dev->flags |= IFF_NOARP;
1465 dev->addr_len = sizeof(struct in6_addr); 1472 dev->addr_len = sizeof(struct in6_addr);
1466 dev->features |= NETIF_F_NETNS_LOCAL;
1467 dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; 1473 dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
1468} 1474}
1469 1475
@@ -1479,6 +1485,7 @@ ip6_tnl_dev_init_gen(struct net_device *dev)
1479 struct ip6_tnl *t = netdev_priv(dev); 1485 struct ip6_tnl *t = netdev_priv(dev);
1480 1486
1481 t->dev = dev; 1487 t->dev = dev;
1488 t->net = dev_net(dev);
1482 dev->tstats = alloc_percpu(struct pcpu_tstats); 1489 dev->tstats = alloc_percpu(struct pcpu_tstats);
1483 if (!dev->tstats) 1490 if (!dev->tstats)
1484 return -ENOMEM; 1491 return -ENOMEM;
@@ -1596,9 +1603,9 @@ static int ip6_tnl_newlink(struct net *src_net, struct net_device *dev,
1596static int ip6_tnl_changelink(struct net_device *dev, struct nlattr *tb[], 1603static int ip6_tnl_changelink(struct net_device *dev, struct nlattr *tb[],
1597 struct nlattr *data[]) 1604 struct nlattr *data[])
1598{ 1605{
1599 struct ip6_tnl *t; 1606 struct ip6_tnl *t = netdev_priv(dev);
1600 struct __ip6_tnl_parm p; 1607 struct __ip6_tnl_parm p;
1601 struct net *net = dev_net(dev); 1608 struct net *net = t->net;
1602 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); 1609 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
1603 1610
1604 if (dev == ip6n->fb_tnl_dev) 1611 if (dev == ip6n->fb_tnl_dev)
@@ -1699,14 +1706,24 @@ static struct xfrm6_tunnel ip6ip6_handler __read_mostly = {
1699 1706
1700static void __net_exit ip6_tnl_destroy_tunnels(struct ip6_tnl_net *ip6n) 1707static void __net_exit ip6_tnl_destroy_tunnels(struct ip6_tnl_net *ip6n)
1701{ 1708{
1709 struct net *net = dev_net(ip6n->fb_tnl_dev);
1710 struct net_device *dev, *aux;
1702 int h; 1711 int h;
1703 struct ip6_tnl *t; 1712 struct ip6_tnl *t;
1704 LIST_HEAD(list); 1713 LIST_HEAD(list);
1705 1714
1715 for_each_netdev_safe(net, dev, aux)
1716 if (dev->rtnl_link_ops == &ip6_link_ops)
1717 unregister_netdevice_queue(dev, &list);
1718
1706 for (h = 0; h < HASH_SIZE; h++) { 1719 for (h = 0; h < HASH_SIZE; h++) {
1707 t = rtnl_dereference(ip6n->tnls_r_l[h]); 1720 t = rtnl_dereference(ip6n->tnls_r_l[h]);
1708 while (t != NULL) { 1721 while (t != NULL) {
1709 unregister_netdevice_queue(t->dev, &list); 1722 /* If dev is in the same netns, it has already
1723 * been added to the list by the previous loop.
1724 */
1725 if (!net_eq(dev_net(t->dev), net))
1726 unregister_netdevice_queue(t->dev, &list);
1710 t = rtnl_dereference(t->next); 1727 t = rtnl_dereference(t->next);
1711 } 1728 }
1712 } 1729 }
@@ -1732,6 +1749,10 @@ static int __net_init ip6_tnl_init_net(struct net *net)
1732 if (!ip6n->fb_tnl_dev) 1749 if (!ip6n->fb_tnl_dev)
1733 goto err_alloc_dev; 1750 goto err_alloc_dev;
1734 dev_net_set(ip6n->fb_tnl_dev, net); 1751 dev_net_set(ip6n->fb_tnl_dev, net);
1752 /* FB netdevice is special: we have one, and only one per netns.
1753 * Allowing to move it to another netns is clearly unsafe.
1754 */
1755 ip6n->fb_tnl_dev->features |= NETIF_F_NETNS_LOCAL;
1735 1756
1736 err = ip6_fb_tnl_dev_init(ip6n->fb_tnl_dev); 1757 err = ip6_fb_tnl_dev_init(ip6n->fb_tnl_dev);
1737 if (err < 0) 1758 if (err < 0)