OpenVZ / Virtuozzo kernel development (devel@openvz.org)
 help / color / mirror / Atom feed
From: Konstantin Khorenko <khorenko@virtuozzo.com>
Subject: [Devel] [PATCH DRAFT vz10 5/5] ve/net/ip6_gre: Enable ip6erspan support in Containers under VE_FEATURE_ERSPAN
Date: Wed, 12 Aug 2026 15:04:01 +0200	[thread overview]
Message-ID: <20260812130401.154702-6-khorenko@virtuozzo.com> (raw)
In-Reply-To: <20260812130401.154702-1-khorenko@virtuozzo.com>

Mirror the IPv4 ERSPAN containerization for IPv6. ip6erspan shares the
per-net state (ip6gre_net_id / struct ip6gre_net) and the fallback
device gating with ip6gre/ip6gretap, so unlike IPv4 it cannot use a
separate pernet id. Instead the shared ign is allocated whenever either
VE_FEATURE_IPGRE or VE_FEATURE_ERSPAN is set for the Container, and each
rtnl link operation checks its own feature bit via ve_feature_set().

Changes:

 - ip6gre_init_net() keeps the ign net_generic slot when the CT has
   VE_FEATURE_IPGRE *or* VE_FEATURE_ERSPAN; otherwise the slot is freed
   and lookups keep returning NULL as before.

 - ip6erspan_tap_setup() marks the device NETIF_F_VIRTUAL so that
   register_netdevice() permits it inside a non-super VE.

 - ip6gre_newlink()/ip6gre_changelink() now explicitly require
   VE_FEATURE_IPGRE, and ip6erspan_newlink()/ip6erspan_changelink()
   require VE_FEATURE_ERSPAN. Since the shared ign may now exist due to
   either feature, the previous implicit "ign == NULL means no IPGRE"
   gate is no longer sufficient to tell the two apart, so the per-op
   feature check is mandatory. The checks sit at the top of each op,
   before any ign dereference.

ERSPAN stays disabled by default for Containers (VE_FEATURES_DEF) and
enabled for the host (init_ve has all features), so host behaviour is
unchanged.

https://virtuozzo.atlassian.net/browse/VSTOR-141173

Feature: net: ERSPAN support in Containers
Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
---
 net/ipv6/ip6_gre.c | 28 +++++++++++++++++-----------
 1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index fe867528a0c5b..ffc1830abed00 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -1627,7 +1627,8 @@ static int __net_init ip6gre_init_net(struct net *net)
 	int err;
 
 #ifdef CONFIG_VE
-	if (!(net->owner_ve->features & VE_FEATURE_IPGRE)) {
+	if (!ve_feature_set(net->owner_ve, IPGRE) &&
+	    !ve_feature_set(net->owner_ve, ERSPAN)) {
 		net_generic_free(net, ip6gre_net_id);
 		return 0;
 	}
@@ -2042,14 +2043,12 @@ static int ip6gre_newlink(struct net *src_net, struct net_device *dev,
 	struct ip6gre_net *ign;
 	int err;
 
+	if (!ve_feature_set(dev_net(dev)->owner_ve, IPGRE))
+		return -EACCES;
+
 	ip6gre_netlink_parms(data, &nt->parms);
 	ign = net_generic(net, ip6gre_net_id);
 
-#ifdef CONFIG_VE
-	if (!ign) /* no VE_FEATURE_IPGRE */
-		return -EACCES;
-#endif
-
 	if (nt->parms.collect_md) {
 		if (rtnl_dereference(ign->collect_md_tun))
 			return -EEXIST;
@@ -2109,6 +2108,9 @@ static int ip6gre_changelink(struct net_device *dev, struct nlattr *tb[],
 	struct ip6gre_net *ign = net_generic(t->net, ip6gre_net_id);
 	struct __ip6_tnl_parm p;
 
+	if (!ve_feature_set(dev_net(dev)->owner_ve, IPGRE))
+		return -EACCES;
+
 	t = ip6gre_changelink_common(dev, tb, data, &p, extack);
 	if (IS_ERR(t))
 		return PTR_ERR(t);
@@ -2271,6 +2273,9 @@ static void ip6erspan_tap_setup(struct net_device *dev)
 	dev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS;
 	dev->priv_flags &= ~IFF_TX_SKB_SHARING;
 	dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
+#ifdef CONFIG_VE
+	dev->ve_features = NETIF_F_VIRTUAL;
+#endif
 	netif_keep_dst(dev);
 }
 
@@ -2283,15 +2288,13 @@ static int ip6erspan_newlink(struct net *src_net, struct net_device *dev,
 	struct ip6gre_net *ign;
 	int err;
 
+	if (!ve_feature_set(dev_net(dev)->owner_ve, ERSPAN))
+		return -EACCES;
+
 	ip6gre_netlink_parms(data, &nt->parms);
 	ip6erspan_set_version(data, &nt->parms);
 	ign = net_generic(net, ip6gre_net_id);
 
-#ifdef CONFIG_VE
-	if (!ign) /* no VE_FEATURE_IPGRE */
-		return -EACCES;
-#endif
-
 	if (nt->parms.collect_md) {
 		if (rtnl_dereference(ign->collect_md_tun_erspan))
 			return -EEXIST;
@@ -2331,6 +2334,9 @@ static int ip6erspan_changelink(struct net_device *dev, struct nlattr *tb[],
 	struct __ip6_tnl_parm p;
 	struct ip6_tnl *t;
 
+	if (!ve_feature_set(dev_net(dev)->owner_ve, ERSPAN))
+		return -EACCES;
+
 	t = ip6gre_changelink_common(dev, tb, data, &p, extack);
 	if (IS_ERR(t))
 		return PTR_ERR(t);
-- 
2.43.0


      parent reply	other threads:[~2026-08-12 13:04 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-12 13:03 [Devel] [PATCH DRAFT vz10 0/5] Enable GRE ERSPAN inside Containers Konstantin Khorenko
2026-08-12 13:03 ` [Devel] [PATCH DRAFT vz10 1/5] Revert "ve/net/gre: Disable ERSPAN support in ip_gre module" Konstantin Khorenko
2026-08-12 13:03 ` [Devel] [PATCH DRAFT vz10 2/5] ve/net/gre: Enable ERSPAN support in Containers under VE_FEATURE_ERSPAN Konstantin Khorenko
2026-08-12 13:03 ` [Devel] [PATCH DRAFT vz10 3/5] ve/net/ip6_gre: Mark ip6gretap devices as movable into a Container Konstantin Khorenko
2026-08-12 13:04 ` [Devel] [PATCH DRAFT vz10 4/5] ve/net/ip6_gre: Fix NULL deref when creating ip6gre/ip6erspan without VE_FEATURE_IPGRE Konstantin Khorenko
2026-08-12 13:04 ` Konstantin Khorenko [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260812130401.154702-6-khorenko@virtuozzo.com \
    --to=khorenko@virtuozzo.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox