FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

sit: add support of x-netns · fabgithub/linux@5e6700b · GitHub

Repository navigation

Commit 5e6700b

Browse files
authored andcommitted
sit: add support of x-netns
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>
1 parent 621e84d commit 5e6700b

3 files changed

Lines changed: 42 additions & 11 deletions

File tree

‎include/net/ip_tunnels.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ struct ip_tunnel {
4242
struct ip_tunnel __rcu *next;
4343
struct hlist_node hash_node;
4444
struct net_device *dev;
45+
struct net *net; /* netns for packet i/o */
4546

4647
int err_count; /* Number of arrived ICMP errors */
4748
unsigned long err_time; /* Time when the last ICMP error

‎net/ipv4/ip_tunnel.c‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@ static struct net_device *__ip_tunnel_create(struct net *net,
304304

305305
tunnel = netdev_priv(dev);
306306
tunnel->parms = *parms;
307+
tunnel->net = net;
307308

308309
err = register_netdevice(dev);
309310
if (err)
@@ -453,6 +454,9 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
453454
tstats->rx_bytes += skb->len;
454455
u64_stats_update_end(&tstats->syncp);
455456

457+
if (tunnel->net != dev_net(tunnel->dev))
458+
skb_scrub_packet(skb);
459+
456460
if (tunnel->dev->type == ARPHRD_ETHER) {
457461
skb->protocol = eth_type_trans(skb, tunnel->dev);
458462
skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
@@ -541,7 +545,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
541545
tos = ipv6_get_dsfield((const struct ipv6hdr *)inner_iph);
542546
}
543547

544-
rt = ip_route_output_tunnel(dev_net(dev), &fl4,
548+
rt = ip_route_output_tunnel(tunnel->net, &fl4,
545549
protocol,
546550
dst, tnl_params->saddr,
547551
tunnel->parms.o_key,
@@ -602,6 +606,9 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
602606
}
603607
#endif
604608

609+
if (tunnel->net != dev_net(dev))
610+
skb_scrub_packet(skb);
611+
605612
if (tunnel->err_count > 0) {
606613
if (time_before(jiffies,
607614
tunnel->err_time + IPTUNNEL_ERR_TIMEO)) {
@@ -888,6 +895,7 @@ int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[],
888895
if (ip_tunnel_find(itn, p, dev->type))
889896
return -EEXIST;
890897

898+
nt->net = net;
891899
nt->parms = *p;
892900
err = register_netdevice(dev);
893901
if (err)

‎net/ipv6/sit.c‎

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -466,14 +466,14 @@ isatap_chksrc(struct sk_buff *skb, const struct iphdr *iph, struct ip_tunnel *t)
466466

467467
static void ipip6_tunnel_uninit(struct net_device *dev)
468468
{
469-
struct net *net = dev_net(dev);
470-
struct sit_net *sitn = net_generic(net, sit_net_id);
469+
struct ip_tunnel *tunnel = netdev_priv(dev);
470+
struct sit_net *sitn = net_generic(tunnel->net, sit_net_id);
471471

472472
if (dev == sitn->fb_tunnel_dev) {
473473
RCU_INIT_POINTER(sitn->tunnels_wc[0], NULL);
474474
} else {
475-
ipip6_tunnel_unlink(sitn, netdev_priv(dev));
476-
ipip6_tunnel_del_prl(netdev_priv(dev), NULL);
475+
ipip6_tunnel_unlink(sitn, tunnel);
476+
ipip6_tunnel_del_prl(tunnel, NULL);
477477
}
478478
dev_put(dev);
479479
}
@@ -621,6 +621,8 @@ static int ipip6_rcv(struct sk_buff *skb)
621621
tstats->rx_packets++;
622622
tstats->rx_bytes += skb->len;
623623

624+
if (tunnel->net != dev_net(tunnel->dev))
625+
skb_scrub_packet(skb);
624626
netif_rx(skb);
625627

626628
return 0;
@@ -803,7 +805,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
803805
goto tx_error;
804806
}
805807

806-
rt = ip_route_output_ports(dev_net(dev), &fl4, NULL,
808+
rt = ip_route_output_ports(tunnel->net, &fl4, NULL,
807809
dst, tiph->saddr,
808810
0, 0,
809811
IPPROTO_IPV6, RT_TOS(tos),
@@ -858,6 +860,9 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
858860
tunnel->err_count = 0;
859861
}
860862

863+
if (tunnel->net != dev_net(dev))
864+
skb_scrub_packet(skb);
865+
861866
/*
862867
* Okay, now see if we can stuff it in the buffer as-is.
863868
*/
@@ -944,7 +949,8 @@ static void ipip6_tunnel_bind_dev(struct net_device *dev)
944949
iph = &tunnel->parms.iph;
945950

946951
if (iph->daddr) {
947-
struct rtable *rt = ip_route_output_ports(dev_net(dev), &fl4, NULL,
952+
struct rtable *rt = ip_route_output_ports(tunnel->net, &fl4,
953+
NULL,
948954
iph->daddr, iph->saddr,
949955
0, 0,
950956
IPPROTO_IPV6,
@@ -959,7 +965,7 @@ static void ipip6_tunnel_bind_dev(struct net_device *dev)
959965
}
960966

961967
if (!tdev && tunnel->parms.link)
962-
tdev = __dev_get_by_index(dev_net(dev), tunnel->parms.link);
968+
tdev = __dev_get_by_index(tunnel->net, tunnel->parms.link);
963969

964970
if (tdev) {
965971
dev->hard_header_len = tdev->hard_header_len + sizeof(struct iphdr);
@@ -972,7 +978,7 @@ static void ipip6_tunnel_bind_dev(struct net_device *dev)
972978

973979
static void ipip6_tunnel_update(struct ip_tunnel *t, struct ip_tunnel_parm *p)
974980
{
975-
struct net *net = dev_net(t->dev);
981+
struct net *net = t->net;
976982
struct sit_net *sitn = net_generic(net, sit_net_id);
977983

978984
ipip6_tunnel_unlink(sitn, t);
@@ -1248,7 +1254,6 @@ static void ipip6_tunnel_setup(struct net_device *dev)
12481254
dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
12491255
dev->iflink = 0;
12501256
dev->addr_len = 4;
1251-
dev->features |= NETIF_F_NETNS_LOCAL;
12521257
dev->features |= NETIF_F_LLTX;
12531258
}
12541259

@@ -1257,6 +1262,7 @@ static int ipip6_tunnel_init(struct net_device *dev)
12571262
struct ip_tunnel *tunnel = netdev_priv(dev);
12581263

12591264
tunnel->dev = dev;
1265+
tunnel->net = dev_net(dev);
12601266

12611267
memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4);
12621268
memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
@@ -1277,6 +1283,7 @@ static int __net_init ipip6_fb_tunnel_init(struct net_device *dev)
12771283
struct sit_net *sitn = net_generic(net, sit_net_id);
12781284

12791285
tunnel->dev = dev;
1286+
tunnel->net = dev_net(dev);
12801287
strcpy(tunnel->parms.name, dev->name);
12811288

12821289
iph->version = 4;
@@ -1564,16 +1571,27 @@ static struct xfrm_tunnel ipip_handler __read_mostly = {
15641571

15651572
static void __net_exit sit_destroy_tunnels(struct sit_net *sitn, struct list_head *head)
15661573
{
1574+
struct net *net = dev_net(sitn->fb_tunnel_dev);
1575+
struct net_device *dev, *aux;
15671576
int prio;
15681577

1578+
for_each_netdev_safe(net, dev, aux)
1579+
if (dev->rtnl_link_ops == &sit_link_ops)
1580+
unregister_netdevice_queue(dev, head);
1581+
15691582
for (prio = 1; prio < 4; prio++) {
15701583
int h;
15711584
for (h = 0; h < HASH_SIZE; h++) {
15721585
struct ip_tunnel *t;
15731586

15741587
t = rtnl_dereference(sitn->tunnels[prio][h]);
15751588
while (t != NULL) {
1576-
unregister_netdevice_queue(t->dev, head);
1589+
/* If dev is in the same netns, it has already
1590+
* been added to the list by the previous loop.
1591+
*/
1592+
if (dev_net(t->dev) != net)
1593+
unregister_netdevice_queue(t->dev,
1594+
head);
15771595
t = rtnl_dereference(t->next);
15781596
}
15791597
}
@@ -1598,6 +1616,10 @@ static int __net_init sit_init_net(struct net *net)
15981616
goto err_alloc_dev;
15991617
}
16001618
dev_net_set(sitn->fb_tunnel_dev, net);
1619+
/* FB netdevice is special: we have one, and only one per netns.
1620+
* Allowing to move it to another netns is clearly unsafe.
1621+
*/
1622+
sitn->fb_tunnel_dev->features |= NETIF_F_NETNS_LOCAL;
16011623

16021624
err = ipip6_fb_tunnel_init(sitn->fb_tunnel_dev);
16031625
if (err)

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL