[Devel] [PATCH RH8 06/11] net/gre: Consider VE_FEATURE_IPGRE on new net creation

Andrey Zhadchenko andrey.zhadchenko at virtuozzo.com
Fri Jun 4 17:45:33 MSK 2021


From: Kirill Gorkunov <gorcunov at virtuozzo.com>

If we load gre module on the node, say we need gre transport on the
node for some reason, this will affect containers -- they won't be
checkpointable (due to lack of support in userspace) until the module
is unloaded from the node again. We have a special feature bit to
control this tansport creation, lets start consideing its value.

https://jira.sw.ru/browse/PSBM-84241

Signed-off-by: Cyrill Gorcunov <gorcunov at virtuozzo.com>

Rebased to vz8:
- With ms commit 64bc17811b72 ("ipv4: speedup ipv6 tunnels dismantle")
tunnels started to use ops->exit_batch with ip_tunnel_delete_nets
instead of ip_tunnel_delete_net and ops->exit, which this commit modified
With rebase commit 70e5af2252244 ("net: Make ipip feature optional")
ip_tunnel_delete_nets is aware of itn being NULL in some net namespaces.
So we can safely drop op->exit hunks.
- Use net_generic_free instead of net_assign_generic for the same reasons
as 70e5af2252244 ("net: Make ipip feature optional")

(cherry-picked from 2db99ab7bfe26fdc2002797b418f3ed15a412bce)
Signed-off-by: Andrey Zhadchenko <andrey.zhadchenko at virtuozzo.com>

diff --git a/include/uapi/linux/vzcalluser.h b/include/uapi/linux/vzcalluser.h
index 8a4ff00..a7f7268 100644
--- a/include/uapi/linux/vzcalluser.h
+++ b/include/uapi/linux/vzcalluser.h
@@ -42,7 +42,7 @@ struct vzctl_ve_configure {
 #define VE_FEATURE_SIT          (1ULL << 3)
 #define VE_FEATURE_IPIP         (1ULL << 4)
 #define VE_FEATURE_PPP		(1ULL << 5)
-#define VE_FEATURE_IPGRE	(1ULL << 6)	/* deprecated */
+#define VE_FEATURE_IPGRE	(1ULL << 6)
 #define VE_FEATURE_BRIDGE	(1ULL << 7)
 #define VE_FEATURE_NFSD		(1ULL << 8)
 
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 16f0c2c..5bd4892 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -50,6 +50,9 @@
 #include <net/dst_metadata.h>
 #include <net/erspan.h>
 
+#include <uapi/linux/vzcalluser.h>
+#include <linux/ve.h>
+
 /*
    Problems & solutions
    --------------------
@@ -982,6 +985,12 @@ static int ipgre_tunnel_init(struct net_device *dev)
 
 static int __net_init ipgre_init_net(struct net *net)
 {
+#ifdef CONFIG_VE
+	if (!(net->owner_ve->features & VE_FEATURE_IPGRE)) {
+		net_generic_free(net, ipgre_net_id);
+		return 0;
+	}
+#endif
 	return ip_tunnel_init_net(net, ipgre_net_id, &ipgre_link_ops, NULL);
 }
 
@@ -1280,6 +1289,11 @@ static int ipgre_newlink(struct net *src_net, struct net_device *dev,
 	__u32 fwmark = 0;
 	int err;
 
+#ifdef CONFIG_VE
+	if (!(dev_net(dev)->owner_ve->features & VE_FEATURE_IPGRE))
+		return -EACCES;
+#endif
+
 	if (ipgre_netlink_encap_parms(data, &ipencap)) {
 		struct ip_tunnel *t = netdev_priv(dev);
 		err = ip_tunnel_encap_setup(t, &ipencap);
@@ -1568,6 +1582,12 @@ struct net_device *gretap_fb_dev_create(struct net *net, const char *name,
 
 static int __net_init ipgre_tap_init_net(struct net *net)
 {
+#ifdef CONFIG_VE
+	if (!(net->owner_ve->features & VE_FEATURE_IPGRE)) {
+		net_generic_free(net, gre_tap_net_id);
+		return 0;
+	}
+#endif
 	return ip_tunnel_init_net(net, gre_tap_net_id, &ipgre_tap_ops, "gretap0");
 }
 
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index f57cb3f..fdb6186 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -103,6 +103,10 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn,
 	struct net_device *ndev;
 	unsigned int hash;
 
+#ifdef CONFIG_VE
+	if (!itn) /* no VE_FEATURE_IPGRE */
+		return NULL;
+#endif
 	hash = ip_tunnel_hash(key, remote);
 	head = &itn->tunnels[hash];
 
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 1144550..015038b 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -58,6 +58,7 @@
 #include <net/erspan.h>
 #include <net/dst_metadata.h>
 
+#include <uapi/linux/vzcalluser.h>
 
 static bool log_ecn_error = true;
 module_param(log_ecn_error, bool, 0644);
@@ -134,6 +135,11 @@ static struct ip6_tnl *ip6gre_tunnel_lookup(struct net_device *dev,
 	int score, cand_score = 4;
 	struct net_device *ndev;
 
+#ifdef CONFIG_VE
+	if (!ign) /* no VE_FEATURE_IPGRE */
+		return NULL;
+#endif
+
 	for_each_ip_tunnel_rcu(t, ign->tunnels_r_l[h0 ^ h1]) {
 		if (!ipv6_addr_equal(local, &t->parms.laddr) ||
 		    !ipv6_addr_equal(remote, &t->parms.raddr) ||
@@ -1536,6 +1542,11 @@ static void ip6gre_destroy_tunnels(struct net *net, struct list_head *head)
 	struct net_device *dev, *aux;
 	int prio;
 
+#ifdef CONFIG_VE
+	if (!ign) /* no VE_FEATURE_IPGRE */
+		return;
+#endif
+
 	for_each_netdev_safe(net, dev, aux)
 		if (dev->rtnl_link_ops == &ip6gre_link_ops ||
 		    dev->rtnl_link_ops == &ip6gre_tap_ops ||
@@ -1568,6 +1579,13 @@ static int __net_init ip6gre_init_net(struct net *net)
 	struct net_device *ndev;
 	int err;
 
+#ifdef CONFIG_VE
+	if (!(net->owner_ve->features & VE_FEATURE_IPGRE)) {
+		net_generic_free(net, ip6gre_net_id);
+		return 0;
+	}
+#endif
+
 	if (!net_has_fallback_tunnels(net))
 		return 0;
 	ndev = alloc_netdev(sizeof(struct ip6_tnl), "ip6gre0",
@@ -1949,6 +1967,11 @@ static int ip6gre_newlink_common(struct net *src_net, struct net_device *dev,
 	struct ip_tunnel_encap ipencap;
 	int err;
 
+#ifdef CONFIG_VE
+	if (!ign) /* no VE_FEATURE_IPGRE */
+		return -EACCES;
+#endif
+
 	nt = netdev_priv(dev);
 
 	if (ip6gre_netlink_encap_parms(data, &ipencap)) {
-- 
1.8.3.1



More information about the Devel mailing list