[Devel] [PATCH vz9] ve/net: ip6_vti: skip per net init in ve

Nikita Yushchenko nikita.yushchenko at virtuozzo.com
Thu Jan 27 19:31:06 MSK 2022


Commit 3e91517559e2 ("ve/net: ip_vti: skip per net init in ve") skips
ip_vti initialization in non-root ve.

Everything written in that commit is true for ip6_vti as well, thus
ip6_vti must be handled it in the same way.

Technical note:
  ip6_vti has much more code locations referencing it's net_generic()
  than it's ip4 counterpart. Adding a check for NULL to all those
  locations is not needed, it is enough to cover pernet ops entry points,
  xfrm protocol entry points, and netdev init. Other netdev ops can't
  get called in non-root VE as long as init errors out.

https://jira.sw.ru/browse/PSBM-138093
Signed-off-by: Nikita Yushchenko <nikita.yushchenko at virtuozzo.com>
Feature: net: whitelist allowed Container network devices
---
 net/ipv6/ip6_vti.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
index 2d048e21abbb..e2bc110f3725 100644
--- a/net/ipv6/ip6_vti.c
+++ b/net/ipv6/ip6_vti.c
@@ -47,6 +47,8 @@
 #include <net/netns/generic.h>
 #include <linux/etherdevice.h>
 
+#include <linux/ve.h>
+
 #define IP6_VTI_HASH_SIZE_SHIFT  5
 #define IP6_VTI_HASH_SIZE (1 << IP6_VTI_HASH_SIZE_SHIFT)
 
@@ -94,6 +96,9 @@ vti6_tnl_lookup(struct net *net, const struct in6_addr *remote,
 	struct vti6_net *ip6n = net_generic(net, vti6_net_id);
 	struct in6_addr any;
 
+	if (!ip6n)
+		return NULL;
+
 	for_each_vti6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
 		if (ipv6_addr_equal(local, &t->parms.laddr) &&
 		    ipv6_addr_equal(remote, &t->parms.raddr) &&
@@ -1010,6 +1015,9 @@ static int vti6_newlink(struct net *src_net, struct net_device *dev,
 	struct net *net = dev_net(dev);
 	struct ip6_tnl *nt;
 
+	if (!net_generic(net, vti6_net_id))
+		return -EACCES;
+
 	nt = netdev_priv(dev);
 	vti6_netlink_parms(data, &nt->parms);
 
@@ -1136,10 +1144,16 @@ static void __net_exit vti6_destroy_tunnels(struct vti6_net *ip6n,
 
 static int __net_init vti6_init_net(struct net *net)
 {
-	struct vti6_net *ip6n = net_generic(net, vti6_net_id);
+	struct vti6_net *ip6n;
 	struct ip6_tnl *t = NULL;
 	int err;
 
+	if (!ve_is_super(net->owner_ve)) {
+		net_generic_free(net, vti6_net_id);
+		return 0;
+	}
+
+	ip6n = net_generic(net, vti6_net_id);
 	ip6n->tnls[0] = ip6n->tnls_wc;
 	ip6n->tnls[1] = ip6n->tnls_r_l;
 
@@ -1182,7 +1196,8 @@ static void __net_exit vti6_exit_batch_net(struct list_head *net_list)
 	rtnl_lock();
 	list_for_each_entry(net, net_list, exit_list) {
 		ip6n = net_generic(net, vti6_net_id);
-		vti6_destroy_tunnels(ip6n, &list);
+		if (ip6n)
+			vti6_destroy_tunnels(ip6n, &list);
 	}
 	unregister_netdevice_many(&list);
 	rtnl_unlock();
-- 
2.30.2



More information about the Devel mailing list