net: do not create fallback tunnels for non-default namespaces
fallback tunnels (like tunl0, gre0, gretap0, erspan0, sit0, ip6tnl0, ip6gre0) are automatically created when the corresponding module is loaded. These tunnels are also automatically created when a new network namespace is created, at a great cost. In many cases, netns are used for isolation purposes, and these extra network devices are a waste of resources. We are using thousands of netns per host, and hit the netns creation/delete bottleneck a lot. (Many thanks to Kirill for recent work on this) Add a new sysctl so that we can opt-out from this automatic creation. Note that these tunnels are still created for the initial namespace, to be the least intrusive for typical setups. Tested: lpk43:~# cat add_del_unshare.sh for i in `seq 1 40` do (for j in `seq 1 100` ; do unshare -n /bin/true >/dev/null ; done) & done wait lpk43:~# echo 0 >/proc/sys/net/core/fb_tunnels_only_for_init_net lpk43:~# time ./add_del_unshare.sh real 0m37.521s user 0m0.886s sys 7m7.084s lpk43:~# echo 1 >/proc/sys/net/core/fb_tunnels_only_for_init_net lpk43:~# time ./add_del_unshare.sh real 0m4.761s user 0m0.851s sys 1m8.343s lpk43:~# Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
2b3905de8b
commit
79134e6ce2
@@ -236,7 +236,7 @@ static struct ip6_tnl *ip6gre_tunnel_lookup(struct net_device *dev,
|
||||
return t;
|
||||
|
||||
dev = ign->fb_tunnel_dev;
|
||||
if (dev->flags & IFF_UP)
|
||||
if (dev && dev->flags & IFF_UP)
|
||||
return netdev_priv(dev);
|
||||
|
||||
return NULL;
|
||||
@@ -1472,6 +1472,8 @@ static int __net_init ip6gre_init_net(struct net *net)
|
||||
struct ip6gre_net *ign = net_generic(net, ip6gre_net_id);
|
||||
int err;
|
||||
|
||||
if (!net_has_fallback_tunnels(net))
|
||||
return 0;
|
||||
ign->fb_tunnel_dev = alloc_netdev(sizeof(struct ip6_tnl), "ip6gre0",
|
||||
NET_NAME_UNKNOWN,
|
||||
ip6gre_tunnel_setup);
|
||||
|
@@ -2205,6 +2205,8 @@ static int __net_init ip6_tnl_init_net(struct net *net)
|
||||
ip6n->tnls[0] = ip6n->tnls_wc;
|
||||
ip6n->tnls[1] = ip6n->tnls_r_l;
|
||||
|
||||
if (!net_has_fallback_tunnels(net))
|
||||
return 0;
|
||||
err = -ENOMEM;
|
||||
ip6n->fb_tnl_dev = alloc_netdev(sizeof(struct ip6_tnl), "ip6tnl0",
|
||||
NET_NAME_UNKNOWN, ip6_tnl_dev_setup);
|
||||
|
@@ -182,7 +182,7 @@ static void ipip6_tunnel_clone_6rd(struct net_device *dev, struct sit_net *sitn)
|
||||
#ifdef CONFIG_IPV6_SIT_6RD
|
||||
struct ip_tunnel *t = netdev_priv(dev);
|
||||
|
||||
if (dev == sitn->fb_tunnel_dev) {
|
||||
if (dev == sitn->fb_tunnel_dev || !sitn->fb_tunnel_dev) {
|
||||
ipv6_addr_set(&t->ip6rd.prefix, htonl(0x20020000), 0, 0, 0);
|
||||
t->ip6rd.relay_prefix = 0;
|
||||
t->ip6rd.prefixlen = 16;
|
||||
@@ -1835,6 +1835,9 @@ static int __net_init sit_init_net(struct net *net)
|
||||
sitn->tunnels[2] = sitn->tunnels_r;
|
||||
sitn->tunnels[3] = sitn->tunnels_r_l;
|
||||
|
||||
if (!net_has_fallback_tunnels(net))
|
||||
return 0;
|
||||
|
||||
sitn->fb_tunnel_dev = alloc_netdev(sizeof(struct ip_tunnel), "sit0",
|
||||
NET_NAME_UNKNOWN,
|
||||
ipip6_tunnel_setup);
|
||||
|
Reference in New Issue
Block a user