Netdev List
 help / color / mirror / Atom feed
* [PATCH net-next 0/6] openvswitch: remove support for legacy tunnel ports
@ 2026-08-04 18:20 Ilya Maximets
  2026-08-04 18:20 ` [PATCH net-next 1/6] openvswitch: remove support for legacy tunnel types Ilya Maximets
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Ilya Maximets @ 2026-08-04 18:20 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Aaron Conole, Eelco Chaudron,
	David Ahern, Ido Schimmel, Shuah Khan, Kuniyuki Iwashima,
	Nikolay Aleksandrov, Fernando Fernandez Mancera, Antoine Tenart,
	linux-kernel, dev, linux-kselftest, Ilya Maximets

ovs-vswitchd doesn't use OVS_VPORT_TYPE_GRE/VXLAN/GENEVE with the
Linux kernel module since adding support for standard tunnel devices
with COLLECT_METADATA back in 2017.  The code to use them was only
activated as a fallback for old kernels, so not used in practice.  And
it is now fully removed in the upcoming OVS 4.0 release.

Modern way to use tunnels with OVS is to create standard tunnel ports
with RTM_NEWLINK + COLLECT_METADATA and add them as OVS_VPORT_TYPE_NETDEV.

Device reference management and the netlink options parsing for these
legacy port types is complicated and was a CVE magnet in the previous
release cycles.  Existence of these modules also makes locking analysis
for geneve module and other core tunnel devices unnecessarily more
complicated, especially in light of migration to per-netns locking:
  https://lore.kernel.org/r/CAAVpQUDmZEaQNDSySLayqexgTrUbhBaL7XPCt9XNQzh+NGQ=UQ@mail.gmail.com

Since there are no actual users for these port types for a very long
time, let's just remove the support entirely.  There is no practical
reason to run OVS from 2017 on a recent kernel.

While it's technically a uAPI change in some sense, from the user's
perspective this removal looks indistinguishable from the kernel built
with CONFIG_OPENVSWITCH_GENEVE/VXLAN/GRE disabled.  And it seems like
removal of unused drivers/modules is not a rare event these days.


There are 3 parts to this set:

1. The first patch does the tunnel port removal, which is the primary
   goal here.

2. Patches 2 and 3 remove extra infrastructure that is no longer in
   use by anything inside the openvswitch module.

3. Patches 4-6 remove functions from gre/vxlan/geneve modules that
   were added for openvswitch in the past to support the tunnel types.
   openvswitch is the only in-tree consumer of these functions.


Version 1:
 - Rebased.
 - Removed the tunnel modules from the new OVS selftest config.
 - Addressed RFC review from Sashiko:
   * Made ovs_netdev_link() static.
   * Restored -EOPNOTSUPP if OVS_VPORT_ATTR_OPTIONS was provided.
   * Removed retry in ovs_vport_cmd_new() as not needed anymore.

RFC:
 - https://lore.kernel.org/r/20260513183559.2141010-1-i.maximets@ovn.org

Ilya Maximets (6):
  openvswitch: remove support for legacy tunnel types
  openvswitch: vport: remove infrastructure for vport options
  openvswitch: vport: remove infrastructure for separate modules
  net: geneve: remove unused geneve_dev_create_fb
  net: gre: remove unused gretap_fb_dev_create
  net: vxlan: remove unused vxlan_dev_create

 drivers/net/geneve.c                          |  49 -----
 drivers/net/vxlan/vxlan_core.c                |  42 +----
 include/net/geneve.h                          |   5 -
 include/net/gre.h                             |   2 -
 include/net/vxlan.h                           |   3 -
 include/uapi/linux/openvswitch.h              |  31 +++-
 net/ipv4/ip_gre.c                             |  47 -----
 net/openvswitch/Kconfig                       |  35 ----
 net/openvswitch/Makefile                      |   4 -
 net/openvswitch/datapath.c                    |  28 +--
 net/openvswitch/vport-geneve.c                | 143 ---------------
 net/openvswitch/vport-gre.c                   | 106 -----------
 net/openvswitch/vport-netdev.c                |  29 +--
 net/openvswitch/vport-netdev.h                |   2 -
 net/openvswitch/vport-vxlan.c                 | 172 ------------------
 net/openvswitch/vport.c                       |  79 +-------
 net/openvswitch/vport.h                       |  23 +--
 tools/testing/selftests/net/config            |   3 -
 .../testing/selftests/net/openvswitch/config  |   3 -
 .../selftests/net/openvswitch/openvswitch.sh  |  38 ----
 .../selftests/net/openvswitch/ovs-dpctl.py    |  93 +++-------
 21 files changed, 63 insertions(+), 874 deletions(-)
 delete mode 100644 net/openvswitch/vport-geneve.c
 delete mode 100644 net/openvswitch/vport-gre.c
 delete mode 100644 net/openvswitch/vport-vxlan.c

-- 
2.55.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH net-next 1/6] openvswitch: remove support for legacy tunnel types
  2026-08-04 18:20 [PATCH net-next 0/6] openvswitch: remove support for legacy tunnel ports Ilya Maximets
@ 2026-08-04 18:20 ` Ilya Maximets
  2026-08-04 18:20 ` [PATCH net-next 2/6] openvswitch: vport: remove infrastructure for vport options Ilya Maximets
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ilya Maximets @ 2026-08-04 18:20 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Aaron Conole, Eelco Chaudron,
	David Ahern, Ido Schimmel, Shuah Khan, Kuniyuki Iwashima,
	Nikolay Aleksandrov, Fernando Fernandez Mancera, Antoine Tenart,
	linux-kernel, dev, linux-kselftest, Ilya Maximets

ovs-vswitchd doesn't use OVS_VPORT_TYPE_GRE/VXLAN/GENEVE with the
Linux kernel module since adding support for standard tunnel devices
with COLLECT_METADATA back in 2017.  The code to use them was only
activated as a fallback for old kernels, so not used in practice.  And
it is now fully removed in the upcoming OVS 4.0 release.

Modern way to use tunnels with OVS is to create standard tunnel ports
with RTM_NEWLINK + COLLECT_METADATA and add them as OVS_VPORT_TYPE_NETDEV.

Device reference management and the netlink options parsing for these
legacy port types is complicated and was a CVE magnet in the previous
release cycles.  Existence of these modules also makes locking analysis
for geneve module and other core tunnel devices unnecessarily more
complicated, especially in light of migration to per-netns locking.

Since there are no actual users for these port types for a very long
time, let's just remove the support entirely.  There is no practical
reason to run OVS from 2017 on a recent kernel.

While it's technically a uAPI change in some sense, from the user's
perspective this removal looks indistinguishable from the kernel built
with CONFIG_OPENVSWITCH_GENEVE/VXLAN/GRE disabled.  And it seems like
removal of unused drivers/modules is not a rare event these days.

A comment is added to the uAPI header noting that standard RTM_NEWLINK
with COLLECT_METADATA followed by OVS_VPORT_CMD_NEW with the simple
OVS_VPORT_TYPE_NETDEV should be used instead.

Modules responsible for these tunnel ports are removed as well as
selftests covering this functionality.  Further cleanups will follow.

Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
---
 include/uapi/linux/openvswitch.h              |  31 +++-
 net/openvswitch/Kconfig                       |  35 ----
 net/openvswitch/Makefile                      |   4 -
 net/openvswitch/datapath.c                    |   6 +-
 net/openvswitch/vport-geneve.c                | 143 ---------------
 net/openvswitch/vport-gre.c                   | 106 -----------
 net/openvswitch/vport-netdev.c                |  29 +--
 net/openvswitch/vport-netdev.h                |   2 -
 net/openvswitch/vport-vxlan.c                 | 172 ------------------
 tools/testing/selftests/net/config            |   3 -
 .../testing/selftests/net/openvswitch/config  |   3 -
 .../selftests/net/openvswitch/openvswitch.sh  |  38 ----
 .../selftests/net/openvswitch/ovs-dpctl.py    |  93 +++-------
 13 files changed, 52 insertions(+), 613 deletions(-)
 delete mode 100644 net/openvswitch/vport-geneve.c
 delete mode 100644 net/openvswitch/vport-gre.c
 delete mode 100644 net/openvswitch/vport-vxlan.c

diff --git a/include/uapi/linux/openvswitch.h b/include/uapi/linux/openvswitch.h
index aa2acdbda8f8..440825e65837 100644
--- a/include/uapi/linux/openvswitch.h
+++ b/include/uapi/linux/openvswitch.h
@@ -244,13 +244,33 @@ enum ovs_vport_cmd {
 	OVS_VPORT_CMD_SET
 };
 
+/**
+ * enum ovs_vport_type - OVS vport types for %OVS_VPORT_ATTR_TYPE.
+ * @OVS_VPORT_TYPE_NETDEV: Existing network device attached as a vport.
+ * @OVS_VPORT_TYPE_INTERNAL: Network device implemented by the OVS datapath.
+ * @OVS_VPORT_TYPE_GRE: Legacy GRE tunnel.  Not supported, see below.
+ * @OVS_VPORT_TYPE_VXLAN: Legacy VXLAN tunnel.  Not supported, see below.
+ * @OVS_VPORT_TYPE_GENEVE: Legacy Geneve tunnel.  Not supported, see below.
+ *
+ * The tunnel vport types are not supported.  Instead, create the tunnel device
+ * using %RTM_NEWLINK with the appropriate %IFLA_INFO_KIND (e.g. ``gre``,
+ * ``gretap``, ``vxlan``, ``geneve``, or other tunnel types) and add it as
+ * %OVS_VPORT_TYPE_NETDEV.  To match and set tunnel parameters on a per-flow
+ * basis, the tunnel device should collect metadata.  To do that, some tunnel
+ * types require an explicit flag such as %IFLA_VXLAN_COLLECT_METADATA for
+ * ``vxlan``, while others such as ``bareudp`` collect metadata
+ * unconditionally.
+ */
 enum ovs_vport_type {
+	/* private: */
 	OVS_VPORT_TYPE_UNSPEC,
+	/* public: */
 	OVS_VPORT_TYPE_NETDEV,   /* network device */
 	OVS_VPORT_TYPE_INTERNAL, /* network device implemented by datapath */
-	OVS_VPORT_TYPE_GRE,      /* GRE tunnel. */
-	OVS_VPORT_TYPE_VXLAN,	 /* VXLAN tunnel. */
-	OVS_VPORT_TYPE_GENEVE,	 /* Geneve tunnel. */
+	OVS_VPORT_TYPE_GRE,      /* GRE tunnel (legacy, not supported). */
+	OVS_VPORT_TYPE_VXLAN,	 /* VXLAN tunnel (legacy, not supported). */
+	OVS_VPORT_TYPE_GENEVE,	 /* Geneve tunnel (legacy, not supported). */
+	/* private: */
 	__OVS_VPORT_TYPE_MAX
 };
 
@@ -284,7 +304,7 @@ enum ovs_vport_type {
  * %OVS_VPORT_ATTR_NAME attributes are required.  %OVS_VPORT_ATTR_PORT_NO is
  * optional; if not specified a free port number is automatically selected.
  * Whether %OVS_VPORT_ATTR_OPTIONS is required or optional depends on the type
- * of vport.
+ * of vport.  None of currently supported vport types support options.
  *
  * For other requests, if %OVS_VPORT_ATTR_NAME is specified then it is used to
  * look up the vport to operate on; otherwise dp_idx from the &struct
@@ -336,7 +356,8 @@ enum {
 #define OVS_VXLAN_EXT_MAX (__OVS_VXLAN_EXT_MAX - 1)
 
 
-/* OVS_VPORT_ATTR_OPTIONS attributes for tunnels.
+/* OVS_VPORT_ATTR_OPTIONS attributes for legacy tunnel vports.
+ * Not supported, see the note for enum ovs_vport_type.
  */
 enum {
 	OVS_TUNNEL_ATTR_UNSPEC,
diff --git a/net/openvswitch/Kconfig b/net/openvswitch/Kconfig
index e6aaee92dba4..19ac9ae18f1e 100644
--- a/net/openvswitch/Kconfig
+++ b/net/openvswitch/Kconfig
@@ -40,38 +40,3 @@ config OPENVSWITCH
 	  called openvswitch.
 
 	  If unsure, say N.
-
-config OPENVSWITCH_GRE
-	tristate "Open vSwitch GRE tunneling support"
-	depends on OPENVSWITCH
-	depends on NET_IPGRE
-	default OPENVSWITCH
-	help
-	  If you say Y here, then the Open vSwitch will be able create GRE
-	  vport.
-
-	  Say N to exclude this support and reduce the binary size.
-
-	  If unsure, say Y.
-
-config OPENVSWITCH_VXLAN
-	tristate "Open vSwitch VXLAN tunneling support"
-	depends on OPENVSWITCH
-	depends on VXLAN
-	default OPENVSWITCH
-	help
-	  If you say Y here, then the Open vSwitch will be able create vxlan vport.
-
-	  Say N to exclude this support and reduce the binary size.
-
-	  If unsure, say Y.
-
-config OPENVSWITCH_GENEVE
-	tristate "Open vSwitch Geneve tunneling support"
-	depends on OPENVSWITCH
-	depends on GENEVE
-	default OPENVSWITCH
-	help
-	  If you say Y here, then the Open vSwitch will be able create geneve vport.
-
-	  Say N to exclude this support and reduce the binary size.
diff --git a/net/openvswitch/Makefile b/net/openvswitch/Makefile
index 28982630bef3..46a27ab369f9 100644
--- a/net/openvswitch/Makefile
+++ b/net/openvswitch/Makefile
@@ -22,8 +22,4 @@ ifneq ($(CONFIG_NF_CONNTRACK),)
 openvswitch-y += conntrack.o
 endif
 
-obj-$(CONFIG_OPENVSWITCH_VXLAN)+= vport-vxlan.o
-obj-$(CONFIG_OPENVSWITCH_GENEVE)+= vport-geneve.o
-obj-$(CONFIG_OPENVSWITCH_GRE)	+= vport-gre.o
-
 CFLAGS_openvswitch_trace.o = -I$(src)
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index eaf332b156d7..0506770341af 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -2210,11 +2210,9 @@ static size_t ovs_vport_cmd_msg_size(void)
 	/* OVS_VPORT_ATTR_UPCALL_PID */
 	msgsize += nla_total_size(nr_cpu_ids * sizeof(u32));
 
-	/* OVS_VPORT_ATTR_OPTIONS(OVS_TUNNEL_ATTR_DST_PORT +
-	 *                        OVS_TUNNEL_ATTR_EXTENSION(OVS_VXLAN_EXT_GBP))
+	/* There are no vports supporting OVS_VPORT_ATTR_OPTIONS, so it is
+	 * not included in the message size calculation.
 	 */
-	msgsize += nla_total_size(nla_total_size(sizeof(u16)) +
-				  nla_total_size(nla_total_size(0)));
 
 	return msgsize;
 }
diff --git a/net/openvswitch/vport-geneve.c b/net/openvswitch/vport-geneve.c
deleted file mode 100644
index cb5ea4424ffc..000000000000
--- a/net/openvswitch/vport-geneve.c
+++ /dev/null
@@ -1,143 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright (c) 2014 Nicira, Inc.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/net.h>
-#include <linux/rculist.h>
-#include <linux/udp.h>
-#include <linux/if_vlan.h>
-#include <linux/module.h>
-
-#include <net/geneve.h>
-#include <net/icmp.h>
-#include <net/ip.h>
-#include <net/route.h>
-#include <net/udp.h>
-#include <net/xfrm.h>
-
-#include "datapath.h"
-#include "vport.h"
-#include "vport-netdev.h"
-
-static struct vport_ops ovs_geneve_vport_ops;
-/**
- * struct geneve_port - Keeps track of open UDP ports
- * @dst_port: destination port.
- */
-struct geneve_port {
-	u16 dst_port;
-};
-
-static inline struct geneve_port *geneve_vport(const struct vport *vport)
-{
-	return vport_priv(vport);
-}
-
-static int geneve_get_options(const struct vport *vport,
-			      struct sk_buff *skb)
-{
-	struct geneve_port *geneve_port = geneve_vport(vport);
-
-	if (nla_put_u16(skb, OVS_TUNNEL_ATTR_DST_PORT, geneve_port->dst_port))
-		return -EMSGSIZE;
-	return 0;
-}
-
-static struct vport *geneve_tnl_create(const struct vport_parms *parms)
-{
-	struct net *net = ovs_dp_get_net(parms->dp);
-	struct nlattr *options = parms->options;
-	struct geneve_port *geneve_port;
-	struct net_device *dev;
-	struct vport *vport;
-	struct nlattr *a;
-	u16 dst_port;
-	int err;
-
-	if (!options) {
-		err = -EINVAL;
-		goto error;
-	}
-
-	a = nla_find_nested(options, OVS_TUNNEL_ATTR_DST_PORT);
-	if (a && nla_len(a) == sizeof(u16)) {
-		dst_port = nla_get_u16(a);
-	} else {
-		/* Require destination port from userspace. */
-		err = -EINVAL;
-		goto error;
-	}
-
-	vport = ovs_vport_alloc(sizeof(struct geneve_port),
-				&ovs_geneve_vport_ops, parms);
-	if (IS_ERR(vport))
-		return vport;
-
-	geneve_port = geneve_vport(vport);
-	geneve_port->dst_port = dst_port;
-
-	rtnl_lock();
-	dev = geneve_dev_create_fb(net, parms->name, NET_NAME_USER, dst_port);
-	if (IS_ERR(dev)) {
-		rtnl_unlock();
-		ovs_vport_free(vport);
-		return ERR_CAST(dev);
-	}
-
-	err = dev_change_flags(dev, dev->flags | IFF_UP, NULL);
-	if (err < 0) {
-		rtnl_delete_link(dev, 0, NULL);
-		rtnl_unlock();
-		ovs_vport_free(vport);
-		goto error;
-	}
-
-	vport->dev = dev;
-	netdev_hold(vport->dev, &vport->dev_tracker, GFP_KERNEL);
-
-	rtnl_unlock();
-	return vport;
-error:
-	return ERR_PTR(err);
-}
-
-static struct vport *geneve_create(const struct vport_parms *parms)
-{
-	struct vport *vport;
-
-	vport = geneve_tnl_create(parms);
-	if (IS_ERR(vport))
-		return vport;
-
-	return ovs_netdev_link(vport, true);
-}
-
-static struct vport_ops ovs_geneve_vport_ops = {
-	.type		= OVS_VPORT_TYPE_GENEVE,
-	.create		= geneve_create,
-	.destroy	= ovs_netdev_tunnel_destroy,
-	.get_options	= geneve_get_options,
-	.send		= dev_queue_xmit,
-};
-
-static int __init ovs_geneve_tnl_init(void)
-{
-	return ovs_vport_ops_register(&ovs_geneve_vport_ops);
-}
-
-static void __exit ovs_geneve_tnl_exit(void)
-{
-	ovs_vport_ops_unregister(&ovs_geneve_vport_ops);
-}
-
-module_init(ovs_geneve_tnl_init);
-module_exit(ovs_geneve_tnl_exit);
-
-MODULE_DESCRIPTION("OVS: Geneve switching port");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("vport-type-5");
diff --git a/net/openvswitch/vport-gre.c b/net/openvswitch/vport-gre.c
deleted file mode 100644
index 6cb5a697b396..000000000000
--- a/net/openvswitch/vport-gre.c
+++ /dev/null
@@ -1,106 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (c) 2007-2014 Nicira, Inc.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/if.h>
-#include <linux/skbuff.h>
-#include <linux/ip.h>
-#include <linux/if_tunnel.h>
-#include <linux/if_vlan.h>
-#include <linux/in.h>
-#include <linux/in_route.h>
-#include <linux/inetdevice.h>
-#include <linux/jhash.h>
-#include <linux/list.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/workqueue.h>
-#include <linux/rculist.h>
-#include <net/route.h>
-#include <net/xfrm.h>
-
-#include <net/icmp.h>
-#include <net/ip.h>
-#include <net/ip_tunnels.h>
-#include <net/gre.h>
-#include <net/net_namespace.h>
-#include <net/netns/generic.h>
-#include <net/protocol.h>
-
-#include "datapath.h"
-#include "vport.h"
-#include "vport-netdev.h"
-
-static struct vport_ops ovs_gre_vport_ops;
-
-static struct vport *gre_tnl_create(const struct vport_parms *parms)
-{
-	struct net *net = ovs_dp_get_net(parms->dp);
-	struct net_device *dev;
-	struct vport *vport;
-	int err;
-
-	vport = ovs_vport_alloc(0, &ovs_gre_vport_ops, parms);
-	if (IS_ERR(vport))
-		return vport;
-
-	rtnl_lock();
-	dev = gretap_fb_dev_create(net, parms->name, NET_NAME_USER);
-	if (IS_ERR(dev)) {
-		rtnl_unlock();
-		ovs_vport_free(vport);
-		return ERR_CAST(dev);
-	}
-
-	err = dev_change_flags(dev, dev->flags | IFF_UP, NULL);
-	if (err < 0) {
-		rtnl_delete_link(dev, 0, NULL);
-		rtnl_unlock();
-		ovs_vport_free(vport);
-		return ERR_PTR(err);
-	}
-
-	vport->dev = dev;
-	netdev_hold(vport->dev, &vport->dev_tracker, GFP_KERNEL);
-
-	rtnl_unlock();
-	return vport;
-}
-
-static struct vport *gre_create(const struct vport_parms *parms)
-{
-	struct vport *vport;
-
-	vport = gre_tnl_create(parms);
-	if (IS_ERR(vport))
-		return vport;
-
-	return ovs_netdev_link(vport, true);
-}
-
-static struct vport_ops ovs_gre_vport_ops = {
-	.type		= OVS_VPORT_TYPE_GRE,
-	.create		= gre_create,
-	.send		= dev_queue_xmit,
-	.destroy	= ovs_netdev_tunnel_destroy,
-};
-
-static int __init ovs_gre_tnl_init(void)
-{
-	return ovs_vport_ops_register(&ovs_gre_vport_ops);
-}
-
-static void __exit ovs_gre_tnl_exit(void)
-{
-	ovs_vport_ops_unregister(&ovs_gre_vport_ops);
-}
-
-module_init(ovs_gre_tnl_init);
-module_exit(ovs_gre_tnl_exit);
-
-MODULE_DESCRIPTION("OVS: GRE switching port");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("vport-type-3");
diff --git a/net/openvswitch/vport-netdev.c b/net/openvswitch/vport-netdev.c
index e7e8490a53d8..44808cd0fcff 100644
--- a/net/openvswitch/vport-netdev.c
+++ b/net/openvswitch/vport-netdev.c
@@ -73,7 +73,7 @@ static struct net_device *get_dpdev(const struct datapath *dp)
 	return local->dev;
 }
 
-struct vport *ovs_netdev_link(struct vport *vport, bool tunnel)
+static struct vport *ovs_netdev_link(struct vport *vport)
 {
 	int err;
 
@@ -112,15 +112,12 @@ struct vport *ovs_netdev_link(struct vport *vport, bool tunnel)
 error_master_upper_dev_unlink:
 	netdev_upper_dev_unlink(vport->dev, get_dpdev(vport->dp));
 error_put_unlock:
-	if (tunnel && vport->dev->reg_state == NETREG_REGISTERED)
-		rtnl_delete_link(vport->dev, 0, NULL);
 	netdev_put(vport->dev, &vport->dev_tracker);
 	rtnl_unlock();
 error_free_vport:
 	ovs_vport_free(vport);
 	return ERR_PTR(err);
 }
-EXPORT_SYMBOL_GPL(ovs_netdev_link);
 
 static struct vport *netdev_create(const struct vport_parms *parms)
 {
@@ -152,7 +149,7 @@ static struct vport *netdev_create(const struct vport_parms *parms)
 		goto error_put;
 	}
 
-	return ovs_netdev_link(vport, false);
+	return ovs_netdev_link(vport);
 error_put:
 	netdev_put(vport->dev, &vport->dev_tracker);
 error_free_vport:
@@ -204,28 +201,6 @@ static void netdev_destroy(struct vport *vport)
 	call_rcu(&vport->rcu, vport_netdev_free);
 }
 
-void ovs_netdev_tunnel_destroy(struct vport *vport)
-{
-	rtnl_lock();
-	if (netif_is_ovs_port(vport->dev))
-		ovs_netdev_detach_dev(vport);
-
-	/* We can be invoked by both explicit vport deletion and
-	 * underlying netdev deregistration; delete the link only
-	 * if it's not already shutting down.
-	 */
-	if (vport->dev->reg_state == NETREG_REGISTERED)
-		rtnl_delete_link(vport->dev, 0, NULL);
-
-	/* We can't put the device reference yet, since it can still be in
-	 * use, but rtnl_unlock()->netdev_run_todo() will block until all
-	 * the references are released, so the RCU call must be before it.
-	 */
-	call_rcu(&vport->rcu, vport_netdev_free);
-	rtnl_unlock();
-}
-EXPORT_SYMBOL_GPL(ovs_netdev_tunnel_destroy);
-
 /* Returns null if this device is not attached to a datapath. */
 struct vport *ovs_netdev_get_vport(struct net_device *dev)
 {
diff --git a/net/openvswitch/vport-netdev.h b/net/openvswitch/vport-netdev.h
index 6c0d7366f986..880506f8317e 100644
--- a/net/openvswitch/vport-netdev.h
+++ b/net/openvswitch/vport-netdev.h
@@ -13,11 +13,9 @@
 
 struct vport *ovs_netdev_get_vport(struct net_device *dev);
 
-struct vport *ovs_netdev_link(struct vport *vport, bool tunnel);
 void ovs_netdev_detach_dev(struct vport *);
 
 int __init ovs_netdev_init(void);
 void ovs_netdev_exit(void);
 
-void ovs_netdev_tunnel_destroy(struct vport *vport);
 #endif /* vport_netdev.h */
diff --git a/net/openvswitch/vport-vxlan.c b/net/openvswitch/vport-vxlan.c
deleted file mode 100644
index c1b37b50d29e..000000000000
--- a/net/openvswitch/vport-vxlan.c
+++ /dev/null
@@ -1,172 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (c) 2014 Nicira, Inc.
- * Copyright (c) 2013 Cisco Systems, Inc.
- */
-
-#include <linux/kernel.h>
-#include <linux/skbuff.h>
-#include <linux/openvswitch.h>
-#include <linux/module.h>
-#include <net/udp.h>
-#include <net/ip_tunnels.h>
-#include <net/rtnetlink.h>
-#include <net/vxlan.h>
-
-#include "datapath.h"
-#include "vport.h"
-#include "vport-netdev.h"
-
-static struct vport_ops ovs_vxlan_netdev_vport_ops;
-
-static int vxlan_get_options(const struct vport *vport, struct sk_buff *skb)
-{
-	struct vxlan_dev *vxlan = netdev_priv(vport->dev);
-	__be16 dst_port = vxlan->cfg.dst_port;
-
-	if (nla_put_u16(skb, OVS_TUNNEL_ATTR_DST_PORT, ntohs(dst_port)))
-		return -EMSGSIZE;
-
-	if (vxlan->cfg.flags & VXLAN_F_GBP) {
-		struct nlattr *exts;
-
-		exts = nla_nest_start_noflag(skb, OVS_TUNNEL_ATTR_EXTENSION);
-		if (!exts)
-			return -EMSGSIZE;
-
-		if (vxlan->cfg.flags & VXLAN_F_GBP &&
-		    nla_put_flag(skb, OVS_VXLAN_EXT_GBP))
-			return -EMSGSIZE;
-
-		nla_nest_end(skb, exts);
-	}
-
-	return 0;
-}
-
-static const struct nla_policy exts_policy[OVS_VXLAN_EXT_MAX + 1] = {
-	[OVS_VXLAN_EXT_GBP]	= { .type = NLA_FLAG, },
-};
-
-static int vxlan_configure_exts(struct vport *vport, struct nlattr *attr,
-				struct vxlan_config *conf)
-{
-	struct nlattr *exts[OVS_VXLAN_EXT_MAX + 1];
-	int err;
-
-	if (nla_len(attr) < sizeof(struct nlattr))
-		return -EINVAL;
-
-	err = nla_parse_nested_deprecated(exts, OVS_VXLAN_EXT_MAX, attr,
-					  exts_policy, NULL);
-	if (err < 0)
-		return err;
-
-	if (exts[OVS_VXLAN_EXT_GBP])
-		conf->flags |= VXLAN_F_GBP;
-
-	return 0;
-}
-
-static struct vport *vxlan_tnl_create(const struct vport_parms *parms)
-{
-	struct net *net = ovs_dp_get_net(parms->dp);
-	struct nlattr *options = parms->options;
-	struct net_device *dev;
-	struct vport *vport;
-	struct nlattr *a;
-	int err;
-	struct vxlan_config conf = {
-		.no_share = true,
-		.flags = VXLAN_F_COLLECT_METADATA | VXLAN_F_UDP_ZERO_CSUM6_RX,
-		/* Don't restrict the packets that can be sent by MTU */
-		.mtu = IP_MAX_MTU,
-	};
-
-	if (!options) {
-		err = -EINVAL;
-		goto error;
-	}
-
-	a = nla_find_nested(options, OVS_TUNNEL_ATTR_DST_PORT);
-	if (a && nla_len(a) == sizeof(u16)) {
-		conf.dst_port = htons(nla_get_u16(a));
-	} else {
-		/* Require destination port from userspace. */
-		err = -EINVAL;
-		goto error;
-	}
-
-	vport = ovs_vport_alloc(0, &ovs_vxlan_netdev_vport_ops, parms);
-	if (IS_ERR(vport))
-		return vport;
-
-	a = nla_find_nested(options, OVS_TUNNEL_ATTR_EXTENSION);
-	if (a) {
-		err = vxlan_configure_exts(vport, a, &conf);
-		if (err) {
-			ovs_vport_free(vport);
-			goto error;
-		}
-	}
-
-	rtnl_lock();
-	dev = vxlan_dev_create(net, parms->name, NET_NAME_USER, &conf);
-	if (IS_ERR(dev)) {
-		rtnl_unlock();
-		ovs_vport_free(vport);
-		return ERR_CAST(dev);
-	}
-
-	err = dev_change_flags(dev, dev->flags | IFF_UP, NULL);
-	if (err < 0) {
-		rtnl_delete_link(dev, 0, NULL);
-		rtnl_unlock();
-		ovs_vport_free(vport);
-		goto error;
-	}
-
-	vport->dev = dev;
-	netdev_hold(vport->dev, &vport->dev_tracker, GFP_KERNEL);
-
-	rtnl_unlock();
-	return vport;
-error:
-	return ERR_PTR(err);
-}
-
-static struct vport *vxlan_create(const struct vport_parms *parms)
-{
-	struct vport *vport;
-
-	vport = vxlan_tnl_create(parms);
-	if (IS_ERR(vport))
-		return vport;
-
-	return ovs_netdev_link(vport, true);
-}
-
-static struct vport_ops ovs_vxlan_netdev_vport_ops = {
-	.type			= OVS_VPORT_TYPE_VXLAN,
-	.create			= vxlan_create,
-	.destroy		= ovs_netdev_tunnel_destroy,
-	.get_options		= vxlan_get_options,
-	.send			= dev_queue_xmit,
-};
-
-static int __init ovs_vxlan_tnl_init(void)
-{
-	return ovs_vport_ops_register(&ovs_vxlan_netdev_vport_ops);
-}
-
-static void __exit ovs_vxlan_tnl_exit(void)
-{
-	ovs_vport_ops_unregister(&ovs_vxlan_netdev_vport_ops);
-}
-
-module_init(ovs_vxlan_tnl_init);
-module_exit(ovs_vxlan_tnl_exit);
-
-MODULE_DESCRIPTION("OVS: VXLAN switching port");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("vport-type-4");
diff --git a/tools/testing/selftests/net/config b/tools/testing/selftests/net/config
index a2d14ec9df1a..d83e11298b01 100644
--- a/tools/testing/selftests/net/config
+++ b/tools/testing/selftests/net/config
@@ -117,9 +117,6 @@ CONFIG_NFT_COMPAT=m
 CONFIG_NFT_NAT=m
 CONFIG_NUMA=y
 CONFIG_OPENVSWITCH=m
-CONFIG_OPENVSWITCH_GENEVE=m
-CONFIG_OPENVSWITCH_GRE=m
-CONFIG_OPENVSWITCH_VXLAN=m
 CONFIG_PAGE_POOL_STATS=y
 CONFIG_PROC_SYSCTL=y
 CONFIG_PSAMPLE=m
diff --git a/tools/testing/selftests/net/openvswitch/config b/tools/testing/selftests/net/openvswitch/config
index c659749cd086..05ca6affb510 100644
--- a/tools/testing/selftests/net/openvswitch/config
+++ b/tools/testing/selftests/net/openvswitch/config
@@ -7,9 +7,6 @@ CONFIG_NET_IPGRE_DEMUX=m
 CONFIG_NF_CONNTRACK=m
 CONFIG_NF_CONNTRACK_OVS=y
 CONFIG_OPENVSWITCH=m
-CONFIG_OPENVSWITCH_GENEVE=m
-CONFIG_OPENVSWITCH_GRE=m
-CONFIG_OPENVSWITCH_VXLAN=m
 CONFIG_PSAMPLE=m
 CONFIG_VETH=y
 CONFIG_VLAN_8021Q=y
diff --git a/tools/testing/selftests/net/openvswitch/openvswitch.sh b/tools/testing/selftests/net/openvswitch/openvswitch.sh
index 853dbc1b00d7..f63001dc2510 100755
--- a/tools/testing/selftests/net/openvswitch/openvswitch.sh
+++ b/tools/testing/selftests/net/openvswitch/openvswitch.sh
@@ -26,7 +26,6 @@ tests="
 	netlink_checks				ovsnl: validate netlink attrs and settings
 	upcall_interfaces			ovs: test the upcall interfaces
 	tunnel_metadata				ovs: test extraction of tunnel metadata
-	tunnel_refcount				ovs: test tunnel vport reference cleanup
 	drop_reason				drop: test drop reasons are emitted
 	pop_vlan				vlan: POP_VLAN action strips tag
 	dec_ttl					ttl: dec_ttl decrements IP TTL
@@ -1210,43 +1209,6 @@ test_tunnel_metadata() {
 	return 0
 }
 
-test_tunnel_refcount() {
-	sbxname="test_tunnel_refcount"
-	sbx_add "${sbxname}" || return 1
-
-	ovs_sbx "${sbxname}" ip netns add trefns || return 1
-	on_exit "ovs_sbx ${sbxname} ip netns del trefns"
-
-	for tun_type in gre vxlan geneve; do
-		info "testing ${tun_type} tunnel vport refcount"
-
-		ovs_sbx "${sbxname}" ip netns exec trefns \
-			python3 $ovs_base/ovs-dpctl.py \
-			add-dp dp-${tun_type} || return 1
-
-		ovs_sbx "${sbxname}" ip netns exec trefns \
-			python3 $ovs_base/ovs-dpctl.py \
-			add-if --no-lwt -t ${tun_type} \
-			dp-${tun_type} ovs-${tun_type}0 || return 1
-
-		ovs_wait ip -netns trefns link show \
-			ovs-${tun_type}0 >/dev/null 2>&1 || return 1
-
-		info "deleting dp - may hang if reference counting is broken"
-		ovs_sbx "${sbxname}" ip netns exec trefns \
-			python3 $ovs_base/ovs-dpctl.py \
-			del-dp dp-${tun_type} &
-
-		dev_removed() {
-			! ip -netns trefns link show "$1" >/dev/null 2>&1
-		}
-		ovs_wait dev_removed dp-${tun_type} || return 1
-		ovs_wait dev_removed ovs-${tun_type}0 || return 1
-	done
-
-	return 0
-}
-
 test_pop_vlan() {
 	local sbx="test_pop_vlan"
 	sbx_add "$sbx" || return $?
diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
index f3edd198223f..3ece07d47281 100644
--- a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
+++ b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
@@ -2364,9 +2364,6 @@ class OvsDatapath(GenericNetlinkSocket):
 class OvsVport(GenericNetlinkSocket):
     OVS_VPORT_TYPE_NETDEV = 1
     OVS_VPORT_TYPE_INTERNAL = 2
-    OVS_VPORT_TYPE_GRE = 3
-    OVS_VPORT_TYPE_VXLAN = 4
-    OVS_VPORT_TYPE_GENEVE = 5
 
     class ovs_vport_msg(ovs_dp_msg):
         nla_map = (
@@ -2374,7 +2371,7 @@ class OvsVport(GenericNetlinkSocket):
             ("OVS_VPORT_ATTR_PORT_NO", "uint32"),
             ("OVS_VPORT_ATTR_TYPE", "uint32"),
             ("OVS_VPORT_ATTR_NAME", "asciiz"),
-            ("OVS_VPORT_ATTR_OPTIONS", "vportopts"),
+            ("OVS_VPORT_ATTR_OPTIONS", "none"),
             ("OVS_VPORT_ATTR_UPCALL_PID", "array(uint32)"),
             ("OVS_VPORT_ATTR_STATS", "vportstats"),
             ("OVS_VPORT_ATTR_PAD", "none"),
@@ -2382,13 +2379,6 @@ class OvsVport(GenericNetlinkSocket):
             ("OVS_VPORT_ATTR_NETNSID", "uint32"),
         )
 
-        class vportopts(nla):
-            nla_map = (
-                ("OVS_TUNNEL_ATTR_UNSPEC", "none"),
-                ("OVS_TUNNEL_ATTR_DST_PORT", "uint16"),
-                ("OVS_TUNNEL_ATTR_EXTENSION", "none"),
-            )
-
         class vportstats(nla):
             fields = (
                 ("rx_packets", "=Q"),
@@ -2406,25 +2396,13 @@ class OvsVport(GenericNetlinkSocket):
             return "netdev"
         elif vport_type == OvsVport.OVS_VPORT_TYPE_INTERNAL:
             return "internal"
-        elif vport_type == OvsVport.OVS_VPORT_TYPE_GRE:
-            return "gre"
-        elif vport_type == OvsVport.OVS_VPORT_TYPE_VXLAN:
-            return "vxlan"
-        elif vport_type == OvsVport.OVS_VPORT_TYPE_GENEVE:
-            return "geneve"
         raise ValueError("Unknown vport type:%d" % vport_type)
 
     def str_to_type(vport_type):
-        if vport_type == "netdev":
+        if vport_type in ["netdev", "gre", "vxlan", "geneve"]:
             return OvsVport.OVS_VPORT_TYPE_NETDEV
         elif vport_type == "internal":
             return OvsVport.OVS_VPORT_TYPE_INTERNAL
-        elif vport_type == "gre":
-            return OvsVport.OVS_VPORT_TYPE_GRE
-        elif vport_type == "vxlan":
-            return OvsVport.OVS_VPORT_TYPE_VXLAN
-        elif vport_type == "geneve":
-            return OvsVport.OVS_VPORT_TYPE_GENEVE
         raise ValueError("Unknown vport type: '%s'" % vport_type)
 
     def __init__(self, packet=OvsPacket()):
@@ -2457,16 +2435,18 @@ class OvsVport(GenericNetlinkSocket):
                 raise ne
         return reply
 
-    def attach(self, dpindex, vport_ifname, ptype, dport, lwt):
+    def attach(self, dpindex, vport_ifname, ptype, dport):
         msg = OvsVport.ovs_vport_msg()
 
         msg["cmd"] = OVS_VPORT_CMD_NEW
         msg["version"] = OVS_DATAPATH_VERSION
         msg["reserved"] = 0
         msg["dpifindex"] = dpindex
-        port_type = OvsVport.str_to_type(ptype)
 
         msg["attrs"].append(["OVS_VPORT_ATTR_NAME", vport_ifname])
+        msg["attrs"].append(
+            ["OVS_VPORT_ATTR_TYPE", OvsVport.str_to_type(ptype)]
+        )
         msg["attrs"].append(
             ["OVS_VPORT_ATTR_UPCALL_PID", [self.upcall_packet.epid]]
         )
@@ -2480,36 +2460,21 @@ class OvsVport(GenericNetlinkSocket):
                 if not dport:
                     dport = tnl[1]
 
-                if not lwt:
-                    if tnl[0] == "gre":
-                        # GRE tunnels have no options.
-                        break
-
-                    vportopt = OvsVport.ovs_vport_msg.vportopts()
-                    vportopt["attrs"].append(
-                        ["OVS_TUNNEL_ATTR_DST_PORT", dport]
-                    )
-                    msg["attrs"].append(
-                        ["OVS_VPORT_ATTR_OPTIONS", vportopt]
-                    )
-                else:
-                    port_type = OvsVport.OVS_VPORT_TYPE_NETDEV
-                    ipr = pyroute2.iproute.IPRoute()
-
-                    if tnl[0] == "geneve":
-                        ipr.link("add", ifname=vport_ifname, kind=tnl[0],
-                                 geneve_port=dport,
-                                 geneve_collect_metadata=True,
-                                 geneve_udp_zero_csum6_rx=1)
-                    elif tnl[0] == "gre":
-                        ipr.link("add", ifname=vport_ifname, kind="gretap",
-                                 gre_collect_metadata=True)
-                    elif tnl[0] == "vxlan":
-                        ipr.link("add", ifname=vport_ifname, kind=tnl[0],
-                                 vxlan_learning=0, vxlan_collect_metadata=1,
-                                 vxlan_udp_zero_csum6_rx=1, vxlan_port=dport)
+                ipr = pyroute2.iproute.IPRoute()
+
+                if tnl[0] == "geneve":
+                    ipr.link("add", ifname=vport_ifname, kind=tnl[0],
+                             geneve_port=dport,
+                             geneve_collect_metadata=True,
+                             geneve_udp_zero_csum6_rx=1)
+                elif tnl[0] == "gre":
+                    ipr.link("add", ifname=vport_ifname, kind="gretap",
+                             gre_collect_metadata=True)
+                elif tnl[0] == "vxlan":
+                    ipr.link("add", ifname=vport_ifname, kind=tnl[0],
+                             vxlan_learning=0, vxlan_collect_metadata=1,
+                             vxlan_udp_zero_csum6_rx=1, vxlan_port=dport)
                 break
-        msg["attrs"].append(["OVS_VPORT_ATTR_TYPE", port_type])
 
         try:
             reply = self.nlm_request(
@@ -2937,19 +2902,12 @@ def print_ovsdp_full(dp_lookup_rep, ifindex, ndb=NDB(), vpl=OvsVport()):
     for iface in ndb.interfaces:
         rep = vpl.info(iface.ifname, ifindex)
         if rep is not None:
-            opts = ""
-            vpo = rep.get_attr("OVS_VPORT_ATTR_OPTIONS")
-            if vpo:
-                dpo = vpo.get_attr("OVS_TUNNEL_ATTR_DST_PORT")
-                if dpo:
-                    opts += " tnl-dport:%s" % dpo
             print(
-                "  port %d: %s (%s%s)"
+                "  port %d: %s (%s)"
                 % (
                     rep.get_attr("OVS_VPORT_ATTR_PORT_NO"),
                     rep.get_attr("OVS_VPORT_ATTR_NAME"),
                     OvsVport.type_to_str(rep.get_attr("OVS_VPORT_ATTR_TYPE")),
-                    opts,
                 )
             )
 
@@ -3022,13 +2980,6 @@ def main(argv):
         default=0,
         help="Destination port (0 for default)"
     )
-    addifcmd.add_argument(
-        "-l",
-        "--lwt",
-        action=argparse.BooleanOptionalAction,
-        default=True,
-        help="Use LWT infrastructure instead of vport (default true)."
-    )
     delifcmd = subparsers.add_parser("del-if")
     delifcmd.add_argument("dpname", help="Datapath Name")
     delifcmd.add_argument("delif", help="Interface name for adding")
@@ -3108,7 +3059,7 @@ def main(argv):
             return 1
         dpindex = rep["dpifindex"]
         rep = ovsvp.attach(rep["dpifindex"], args.addif, args.ptype,
-                           args.dport, args.lwt)
+                           args.dport)
         msg = "vport '%s'" % args.addif
         if rep and rep["header"]["error"] is None:
             msg += " added."
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH net-next 2/6] openvswitch: vport: remove infrastructure for vport options
  2026-08-04 18:20 [PATCH net-next 0/6] openvswitch: remove support for legacy tunnel ports Ilya Maximets
  2026-08-04 18:20 ` [PATCH net-next 1/6] openvswitch: remove support for legacy tunnel types Ilya Maximets
@ 2026-08-04 18:20 ` Ilya Maximets
  2026-08-04 18:20 ` [PATCH net-next 3/6] openvswitch: vport: remove infrastructure for separate modules Ilya Maximets
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ilya Maximets @ 2026-08-04 18:20 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Aaron Conole, Eelco Chaudron,
	David Ahern, Ido Schimmel, Shuah Khan, Kuniyuki Iwashima,
	Nikolay Aleksandrov, Fernando Fernandez Mancera, Antoine Tenart,
	linux-kernel, dev, linux-kselftest, Ilya Maximets

Since removal of tunnel vport types, there aren't any vports that
support options.  Let's remove the options-related infrastructure.

Can be reinstated if we ever need a new vport type or if we need extra
options for the existing ones.  The uAPI attribute remains.

Clarification comment is added to highlight that none of the supported
vports support options at the moment.

If the options are provided, the code now directly replies with
-EOPNOTSUPP to keep the behavior the same for remaining vport types.

Note: It is technically possible that someone has an out-of-tree module
named vport-type-N that implements a different vport type and they have
options for this vport type.  However, our message size calculations do
not account for whatever options such a port would have and so it is
dangerous to load such a module without modifying the code in the main
datapath.c, unless the options are smaller than the ones we had for
vxlan.  A more robust solution would be to have a different version of
the entire openvswitch module instead, so the use case of a separate
vport-type-N loaded with the upstream openvswitch module is unlikely.
At this time we're not aware of anyone doing that.

Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
---
 net/openvswitch/datapath.c | 20 +++-----------
 net/openvswitch/vport.c    | 54 --------------------------------------
 net/openvswitch/vport.h    | 14 ----------
 3 files changed, 4 insertions(+), 84 deletions(-)

diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 0506770341af..57c83f05fead 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -1856,7 +1856,6 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
 	/* Set up our datapath device. */
 	parms.name = nla_data(a[OVS_DP_ATTR_NAME]);
 	parms.type = OVS_VPORT_TYPE_INTERNAL;
-	parms.options = NULL;
 	parms.dp = dp;
 	parms.port_no = OVSP_LOCAL;
 	parms.upcall_portids = a[OVS_DP_ATTR_UPCALL_PID];
@@ -2172,10 +2171,6 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb,
 	if (ovs_vport_get_upcall_portids(vport, skb))
 		goto nla_put_failure;
 
-	err = ovs_vport_get_options(vport, skb);
-	if (err == -EMSGSIZE)
-		goto error;
-
 	genlmsg_end(skb, ovs_header);
 	return 0;
 
@@ -2183,7 +2178,6 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb,
 	rcu_read_unlock();
 nla_put_failure:
 	err = -EMSGSIZE;
-error:
 	genlmsg_cancel(skb, ovs_header);
 	return err;
 }
@@ -2210,10 +2204,6 @@ static size_t ovs_vport_cmd_msg_size(void)
 	/* OVS_VPORT_ATTR_UPCALL_PID */
 	msgsize += nla_total_size(nr_cpu_ids * sizeof(u32));
 
-	/* There are no vports supporting OVS_VPORT_ATTR_OPTIONS, so it is
-	 * not included in the message size calculation.
-	 */
-
 	return msgsize;
 }
 
@@ -2365,7 +2355,6 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info)
 	}
 
 	parms.name = nla_data(a[OVS_VPORT_ATTR_NAME]);
-	parms.options = a[OVS_VPORT_ATTR_OPTIONS];
 	parms.dp = dp;
 	parms.port_no = port_no;
 	parms.upcall_portids = a[OVS_VPORT_ATTR_UPCALL_PID];
@@ -2427,12 +2416,11 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info)
 	}
 
 	if (a[OVS_VPORT_ATTR_OPTIONS]) {
-		err = ovs_vport_set_options(vport, a[OVS_VPORT_ATTR_OPTIONS]);
-		if (err)
-			goto exit_unlock_free;
+		/* There are no vport types that support legacy options. */
+		err = -EOPNOTSUPP;
+		goto exit_unlock_free;
 	}
 
-
 	if (a[OVS_VPORT_ATTR_UPCALL_PID]) {
 		struct nlattr *ids = a[OVS_VPORT_ATTR_UPCALL_PID];
 
@@ -2606,7 +2594,7 @@ static const struct nla_policy vport_policy[OVS_VPORT_ATTR_MAX + 1] = {
 	[OVS_VPORT_ATTR_PORT_NO] = { .type = NLA_U32 },
 	[OVS_VPORT_ATTR_TYPE] = { .type = NLA_U32 },
 	[OVS_VPORT_ATTR_UPCALL_PID] = { .type = NLA_UNSPEC },
-	[OVS_VPORT_ATTR_OPTIONS] = { .type = NLA_NESTED },
+	[OVS_VPORT_ATTR_OPTIONS] = { .type = NLA_NESTED }, /* Unused. */
 	[OVS_VPORT_ATTR_IFINDEX] = NLA_POLICY_MIN(NLA_S32, 0),
 	[OVS_VPORT_ATTR_NETNSID] = { .type = NLA_S32 },
 	[OVS_VPORT_ATTR_UPCALL_STATS] = { .type = NLA_NESTED },
diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c
index 12741485c939..ada316a61726 100644
--- a/net/openvswitch/vport.c
+++ b/net/openvswitch/vport.c
@@ -239,22 +239,6 @@ struct vport *ovs_vport_add(const struct vport_parms *parms)
 		return ERR_PTR(-EAGAIN);
 }
 
-/**
- *	ovs_vport_set_options - modify existing vport device (for kernel callers)
- *
- * @vport: vport to modify.
- * @options: New configuration.
- *
- * Modifies an existing device with the specified configuration (which is
- * dependent on device type).  ovs_mutex must be held.
- */
-int ovs_vport_set_options(struct vport *vport, struct nlattr *options)
-{
-	if (!vport->ops->set_options)
-		return -EOPNOTSUPP;
-	return vport->ops->set_options(vport, options);
-}
-
 /**
  *	ovs_vport_del - delete existing vport device
  *
@@ -348,44 +332,6 @@ int ovs_vport_get_upcall_stats(struct vport *vport, struct sk_buff *skb)
 	return 0;
 }
 
-/**
- *	ovs_vport_get_options - retrieve device options
- *
- * @vport: vport from which to retrieve the options.
- * @skb: sk_buff where options should be appended.
- *
- * Retrieves the configuration of the given device, appending an
- * %OVS_VPORT_ATTR_OPTIONS attribute that in turn contains nested
- * vport-specific attributes to @skb.
- *
- * Returns 0 if successful, -EMSGSIZE if @skb has insufficient room, or another
- * negative error code if a real error occurred.  If an error occurs, @skb is
- * left unmodified.
- *
- * Must be called with ovs_mutex or rcu_read_lock.
- */
-int ovs_vport_get_options(const struct vport *vport, struct sk_buff *skb)
-{
-	struct nlattr *nla;
-	int err;
-
-	if (!vport->ops->get_options)
-		return 0;
-
-	nla = nla_nest_start_noflag(skb, OVS_VPORT_ATTR_OPTIONS);
-	if (!nla)
-		return -EMSGSIZE;
-
-	err = vport->ops->get_options(vport, skb);
-	if (err) {
-		nla_nest_cancel(skb, nla);
-		return err;
-	}
-
-	nla_nest_end(skb, nla);
-	return 0;
-}
-
 /**
  *	ovs_vport_set_upcall_portids - set upcall portids of @vport.
  *
diff --git a/net/openvswitch/vport.h b/net/openvswitch/vport.h
index 9f67b9dd49f9..636788b59907 100644
--- a/net/openvswitch/vport.h
+++ b/net/openvswitch/vport.h
@@ -34,9 +34,6 @@ void ovs_vport_get_stats(struct vport *, struct ovs_vport_stats *);
 
 int ovs_vport_get_upcall_stats(struct vport *vport, struct sk_buff *skb);
 
-int ovs_vport_set_options(struct vport *, struct nlattr *options);
-int ovs_vport_get_options(const struct vport *, struct sk_buff *);
-
 int ovs_vport_set_upcall_portids(struct vport *, const struct nlattr *pids);
 int ovs_vport_get_upcall_portids(const struct vport *, struct sk_buff *);
 u32 ovs_vport_find_upcall_portid(const struct vport *, struct sk_buff *);
@@ -92,8 +89,6 @@ struct vport {
  *
  * @name: New vport's name.
  * @type: New vport's type.
- * @options: %OVS_VPORT_ATTR_OPTIONS attribute from Netlink message, %NULL if
- * none was supplied.
  * @desired_ifindex: New vport's ifindex.
  * @dp: New vport's datapath.
  * @port_no: New vport's port number.
@@ -104,7 +99,6 @@ struct vport_parms {
 	const char *name;
 	enum ovs_vport_type type;
 	int desired_ifindex;
-	struct nlattr *options;
 
 	/* For ovs_vport_alloc(). */
 	struct datapath *dp;
@@ -120,11 +114,6 @@ struct vport_parms {
  * a new vport allocated with ovs_vport_alloc(), otherwise an ERR_PTR() value.
  * @destroy: Destroys a vport.  Must call vport_free() on the vport but not
  * before an RCU grace period has elapsed.
- * @set_options: Modify the configuration of an existing vport.  May be %NULL
- * if modification is not supported.
- * @get_options: Appends vport-specific attributes for the configuration of an
- * existing vport to a &struct sk_buff.  May be %NULL for a vport that does not
- * have any configuration.
  * @send: Send a packet on the device.
  * zero for dropped packets or negative for error.
  * @owner: Module that implements this vport type.
@@ -137,9 +126,6 @@ struct vport_ops {
 	struct vport *(*create)(const struct vport_parms *);
 	void (*destroy)(struct vport *);
 
-	int (*set_options)(struct vport *, struct nlattr *);
-	int (*get_options)(const struct vport *, struct sk_buff *);
-
 	int (*send)(struct sk_buff *skb);
 	struct module *owner;
 	struct list_head list;
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH net-next 3/6] openvswitch: vport: remove infrastructure for separate modules
  2026-08-04 18:20 [PATCH net-next 0/6] openvswitch: remove support for legacy tunnel ports Ilya Maximets
  2026-08-04 18:20 ` [PATCH net-next 1/6] openvswitch: remove support for legacy tunnel types Ilya Maximets
  2026-08-04 18:20 ` [PATCH net-next 2/6] openvswitch: vport: remove infrastructure for vport options Ilya Maximets
@ 2026-08-04 18:20 ` Ilya Maximets
  2026-08-04 18:20 ` [PATCH net-next 4/6] net: geneve: remove unused geneve_dev_create_fb Ilya Maximets
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ilya Maximets @ 2026-08-04 18:20 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Aaron Conole, Eelco Chaudron,
	David Ahern, Ido Schimmel, Shuah Khan, Kuniyuki Iwashima,
	Nikolay Aleksandrov, Fernando Fernandez Mancera, Antoine Tenart,
	linux-kernel, dev, linux-kselftest, Ilya Maximets

Since removal of legacy tunnel vport types only the built-in ones
remain.  So, there is no need for the extra infrastructure for dynamic
module loading.  Can be reinstated in the future if we need a new
vport type.

Note: It is technically possible that someone has an out-of-tree
module named vport-type-N that implements a different vport type.
At this time we're not aware of anyone doing that.  People running
out-of-tree modules normally just have an out-of-tree openvswitch
module as a whole.  And there are actually no supported out-of-tree
implementations of the openvswitch module known to the community.

Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
---
 net/openvswitch/datapath.c |  6 +-----
 net/openvswitch/vport.c    | 25 +++----------------------
 net/openvswitch/vport.h    |  9 +--------
 3 files changed, 5 insertions(+), 35 deletions(-)

diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 57c83f05fead..34a15ef76a70 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -2331,7 +2331,6 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info)
 		return -ENOMEM;
 
 	ovs_lock();
-restart:
 	dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
 	err = -ENODEV;
 	if (!dp)
@@ -2363,11 +2362,8 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info)
 
 	vport = new_vport(&parms);
 	err = PTR_ERR(vport);
-	if (IS_ERR(vport)) {
-		if (err == -EAGAIN)
-			goto restart;
+	if (IS_ERR(vport))
 		goto exit_unlock_free;
-	}
 
 	err = ovs_vport_cmd_fill_info(vport, reply, genl_info_net(info),
 				      info->snd_portid, info->snd_seq, 0,
diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c
index ada316a61726..29ebeb164bdc 100644
--- a/net/openvswitch/vport.c
+++ b/net/openvswitch/vport.c
@@ -57,7 +57,7 @@ static struct hlist_head *hash_bucket(const struct net *net, const char *name)
 	return &dev_table[hash & (VPORT_HASH_BUCKETS - 1)];
 }
 
-int __ovs_vport_ops_register(struct vport_ops *ops)
+int ovs_vport_ops_register(struct vport_ops *ops)
 {
 	int err = -EEXIST;
 	struct vport_ops *o;
@@ -73,7 +73,6 @@ int __ovs_vport_ops_register(struct vport_ops *ops)
 	ovs_unlock();
 	return err;
 }
-EXPORT_SYMBOL_GPL(__ovs_vport_ops_register);
 
 void ovs_vport_ops_unregister(struct vport_ops *ops)
 {
@@ -81,7 +80,6 @@ void ovs_vport_ops_unregister(struct vport_ops *ops)
 	list_del(&ops->list);
 	ovs_unlock();
 }
-EXPORT_SYMBOL_GPL(ovs_vport_ops_unregister);
 
 /**
  *	ovs_vport_locate - find a port that has already been created
@@ -210,14 +208,9 @@ struct vport *ovs_vport_add(const struct vport_parms *parms)
 	if (ops) {
 		struct hlist_head *bucket;
 
-		if (!try_module_get(ops->owner))
-			return ERR_PTR(-EAFNOSUPPORT);
-
 		vport = ops->create(parms);
-		if (IS_ERR(vport)) {
-			module_put(ops->owner);
+		if (IS_ERR(vport))
 			return vport;
-		}
 
 		bucket = hash_bucket(ovs_dp_get_net(vport->dp),
 				     ovs_vport_name(vport));
@@ -225,18 +218,7 @@ struct vport *ovs_vport_add(const struct vport_parms *parms)
 		return vport;
 	}
 
-	/* Unlock to attempt module load and return -EAGAIN if load
-	 * was successful as we need to restart the port addition
-	 * workflow.
-	 */
-	ovs_unlock();
-	request_module("vport-type-%d", parms->type);
-	ovs_lock();
-
-	if (!ovs_vport_lookup(parms))
-		return ERR_PTR(-EAFNOSUPPORT);
-	else
-		return ERR_PTR(-EAGAIN);
+	return ERR_PTR(-EAFNOSUPPORT);
 }
 
 /**
@@ -250,7 +232,6 @@ struct vport *ovs_vport_add(const struct vport_parms *parms)
 void ovs_vport_del(struct vport *vport)
 {
 	hlist_del_rcu(&vport->hash_node);
-	module_put(vport->ops->owner);
 	vport->ops->destroy(vport);
 }
 
diff --git a/net/openvswitch/vport.h b/net/openvswitch/vport.h
index 636788b59907..930f1ccc8558 100644
--- a/net/openvswitch/vport.h
+++ b/net/openvswitch/vport.h
@@ -116,7 +116,6 @@ struct vport_parms {
  * before an RCU grace period has elapsed.
  * @send: Send a packet on the device.
  * zero for dropped packets or negative for error.
- * @owner: Module that implements this vport type.
  * @list: List entry in the global list of vport types.
  */
 struct vport_ops {
@@ -127,7 +126,6 @@ struct vport_ops {
 	void (*destroy)(struct vport *);
 
 	int (*send)(struct sk_buff *skb);
-	struct module *owner;
 	struct list_head list;
 };
 
@@ -191,12 +189,7 @@ static inline const char *ovs_vport_name(struct vport *vport)
 	return vport->dev->name;
 }
 
-int __ovs_vport_ops_register(struct vport_ops *ops);
-#define ovs_vport_ops_register(ops)		\
-	({					\
-		(ops)->owner = THIS_MODULE;	\
-		__ovs_vport_ops_register(ops);	\
-	})
+int ovs_vport_ops_register(struct vport_ops *ops);
 
 void ovs_vport_ops_unregister(struct vport_ops *ops);
 void ovs_vport_send(struct vport *vport, struct sk_buff *skb, u8 mac_proto);
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH net-next 4/6] net: geneve: remove unused geneve_dev_create_fb
  2026-08-04 18:20 [PATCH net-next 0/6] openvswitch: remove support for legacy tunnel ports Ilya Maximets
                   ` (2 preceding siblings ...)
  2026-08-04 18:20 ` [PATCH net-next 3/6] openvswitch: vport: remove infrastructure for separate modules Ilya Maximets
@ 2026-08-04 18:20 ` Ilya Maximets
  2026-08-04 18:20 ` [PATCH net-next 5/6] net: gre: remove unused gretap_fb_dev_create Ilya Maximets
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ilya Maximets @ 2026-08-04 18:20 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Aaron Conole, Eelco Chaudron,
	David Ahern, Ido Schimmel, Shuah Khan, Kuniyuki Iwashima,
	Nikolay Aleksandrov, Fernando Fernandez Mancera, Antoine Tenart,
	linux-kernel, dev, linux-kselftest, Ilya Maximets

The only user was vport-geneve in openvswitch and now it is gone.

This also removes the last exported function in geneve module,
significantly reducing complexity of the locking analysis.

Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
---
 drivers/net/geneve.c | 49 --------------------------------------------
 include/net/geneve.h |  5 -----
 2 files changed, 54 deletions(-)

diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
index a6a8978e3b81..0ab729f055ea 100644
--- a/drivers/net/geneve.c
+++ b/drivers/net/geneve.c
@@ -2670,55 +2670,6 @@ static struct rtnl_link_ops geneve_link_ops __read_mostly = {
 	.fill_info	= geneve_fill_info,
 };
 
-struct net_device *geneve_dev_create_fb(struct net *net, const char *name,
-					u8 name_assign_type, u16 dst_port)
-{
-	struct nlattr *tb[IFLA_MAX + 1];
-	struct net_device *dev;
-	LIST_HEAD(list_kill);
-	int err;
-	struct geneve_config cfg = {
-		.df = GENEVE_DF_UNSET,
-		.use_udp6_rx_checksums = true,
-		.ttl_inherit = false,
-		.collect_md = true,
-		.dualstack = true,
-		.port_min = 1,
-		.port_max = USHRT_MAX,
-	};
-
-	memset(tb, 0, sizeof(tb));
-	dev = rtnl_create_link(net, name, name_assign_type,
-			       &geneve_link_ops, tb, NULL);
-	if (IS_ERR(dev))
-		return dev;
-
-	init_tnl_info(&cfg.info, dst_port);
-	err = geneve_configure(net, dev, NULL, &cfg);
-	if (err) {
-		free_netdev(dev);
-		return ERR_PTR(err);
-	}
-
-	/* openvswitch users expect packet sizes to be unrestricted,
-	 * so set the largest MTU we can.
-	 */
-	err = geneve_change_mtu(dev, IP_MAX_MTU);
-	if (err)
-		goto err;
-
-	err = rtnl_configure_link(dev, NULL, 0, NULL);
-	if (err < 0)
-		goto err;
-
-	return dev;
-err:
-	geneve_dellink(dev, &list_kill);
-	unregister_netdevice_many(&list_kill);
-	return ERR_PTR(err);
-}
-EXPORT_SYMBOL_GPL(geneve_dev_create_fb);
-
 static int geneve_netdevice_event(struct notifier_block *unused,
 				  unsigned long event, void *ptr)
 {
diff --git a/include/net/geneve.h b/include/net/geneve.h
index 5c96827a487e..ba2c14d61e90 100644
--- a/include/net/geneve.h
+++ b/include/net/geneve.h
@@ -68,9 +68,4 @@ static inline bool netif_is_geneve(const struct net_device *dev)
 	       !strcmp(dev->rtnl_link_ops->kind, "geneve");
 }
 
-#ifdef CONFIG_INET
-struct net_device *geneve_dev_create_fb(struct net *net, const char *name,
-					u8 name_assign_type, u16 dst_port);
-#endif /*ifdef CONFIG_INET */
-
 #endif /*ifdef__NET_GENEVE_H */
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH net-next 5/6] net: gre: remove unused gretap_fb_dev_create
  2026-08-04 18:20 [PATCH net-next 0/6] openvswitch: remove support for legacy tunnel ports Ilya Maximets
                   ` (3 preceding siblings ...)
  2026-08-04 18:20 ` [PATCH net-next 4/6] net: geneve: remove unused geneve_dev_create_fb Ilya Maximets
@ 2026-08-04 18:20 ` Ilya Maximets
  2026-08-04 18:20 ` [PATCH net-next 6/6] net: vxlan: remove unused vxlan_dev_create Ilya Maximets
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ilya Maximets @ 2026-08-04 18:20 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Aaron Conole, Eelco Chaudron,
	David Ahern, Ido Schimmel, Shuah Khan, Kuniyuki Iwashima,
	Nikolay Aleksandrov, Fernando Fernandez Mancera, Antoine Tenart,
	linux-kernel, dev, linux-kselftest, Ilya Maximets

The only user was vport-gre in openvswitch and now it is gone.

Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
---
 include/net/gre.h |  2 --
 net/ipv4/ip_gre.c | 47 -----------------------------------------------
 2 files changed, 49 deletions(-)

diff --git a/include/net/gre.h b/include/net/gre.h
index ccd293203284..b55f67ecd2fc 100644
--- a/include/net/gre.h
+++ b/include/net/gre.h
@@ -32,8 +32,6 @@ struct gre_protocol {
 int gre_add_protocol(const struct gre_protocol *proto, u8 version);
 int gre_del_protocol(const struct gre_protocol *proto, u8 version);
 
-struct net_device *gretap_fb_dev_create(struct net *net, const char *name,
-				       u8 name_assign_type);
 int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi,
 		     bool *csum_err, __be16 proto, int nhs);
 
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 0ba1e94e9012..6a92607401e8 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -1716,53 +1716,6 @@ static struct rtnl_link_ops erspan_link_ops __read_mostly = {
 	.get_link_net	= ip_tunnel_get_link_net,
 };
 
-struct net_device *gretap_fb_dev_create(struct net *net, const char *name,
-					u8 name_assign_type)
-{
-	struct rtnl_newlink_params params = { .src_net = net };
-	struct nlattr *tb[IFLA_MAX + 1];
-	struct net_device *dev;
-	LIST_HEAD(list_kill);
-	struct ip_tunnel *t;
-	int err;
-
-	memset(&tb, 0, sizeof(tb));
-	params.tb = tb;
-
-	dev = rtnl_create_link(net, name, name_assign_type,
-			       &ipgre_tap_ops, tb, NULL);
-	if (IS_ERR(dev))
-		return dev;
-
-	/* Configure flow based GRE device. */
-	t = netdev_priv(dev);
-	t->collect_md = true;
-
-	err = ipgre_newlink(dev, &params, NULL);
-	if (err < 0) {
-		free_netdev(dev);
-		return ERR_PTR(err);
-	}
-
-	/* openvswitch users expect packet sizes to be unrestricted,
-	 * so set the largest MTU we can.
-	 */
-	err = __ip_tunnel_change_mtu(dev, IP_MAX_MTU, false);
-	if (err)
-		goto out;
-
-	err = rtnl_configure_link(dev, NULL, 0, NULL);
-	if (err < 0)
-		goto out;
-
-	return dev;
-out:
-	ip_tunnel_dellink(dev, &list_kill);
-	unregister_netdevice_many(&list_kill);
-	return ERR_PTR(err);
-}
-EXPORT_SYMBOL_GPL(gretap_fb_dev_create);
-
 static int __net_init ipgre_tap_init_net(struct net *net)
 {
 	return ip_tunnel_init_net(net, gre_tap_net_id, &ipgre_tap_ops, "gretap0");
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH net-next 6/6] net: vxlan: remove unused vxlan_dev_create
  2026-08-04 18:20 [PATCH net-next 0/6] openvswitch: remove support for legacy tunnel ports Ilya Maximets
                   ` (4 preceding siblings ...)
  2026-08-04 18:20 ` [PATCH net-next 5/6] net: gre: remove unused gretap_fb_dev_create Ilya Maximets
@ 2026-08-04 18:20 ` Ilya Maximets
  2026-08-06 11:03 ` [PATCH net-next 0/6] openvswitch: remove support for legacy tunnel ports Paolo Abeni
  2026-08-06 13:20 ` patchwork-bot+netdevbpf
  7 siblings, 0 replies; 9+ messages in thread
From: Ilya Maximets @ 2026-08-04 18:20 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Aaron Conole, Eelco Chaudron,
	David Ahern, Ido Schimmel, Shuah Khan, Kuniyuki Iwashima,
	Nikolay Aleksandrov, Fernando Fernandez Mancera, Antoine Tenart,
	linux-kernel, dev, linux-kselftest, Ilya Maximets

The vport-vxlan in openvswitch was the last user and it is now gone.

And we can now rename the internal function to have a better name.

Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
---
 drivers/net/vxlan/vxlan_core.c | 42 ++++------------------------------
 include/net/vxlan.h            |  3 ---
 2 files changed, 4 insertions(+), 41 deletions(-)

diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
index 25e3fe1ee751..fd5505153d0b 100644
--- a/drivers/net/vxlan/vxlan_core.c
+++ b/drivers/net/vxlan/vxlan_core.c
@@ -3966,9 +3966,9 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
 	return 0;
 }
 
-static int __vxlan_dev_create(struct net *net, struct net_device *dev,
-			      struct vxlan_config *conf,
-			      struct netlink_ext_ack *extack)
+static int vxlan_dev_create(struct net *net, struct net_device *dev,
+			    struct vxlan_config *conf,
+			    struct netlink_ext_ack *extack)
 {
 	struct vxlan_net *vn = net_generic(net, vxlan_net_id);
 	struct vxlan_dev *vxlan = netdev_priv(dev);
@@ -4416,7 +4416,7 @@ static int vxlan_newlink(struct net_device *dev,
 	if (err)
 		return err;
 
-	return __vxlan_dev_create(link_net, dev, &conf, extack);
+	return vxlan_dev_create(link_net, dev, &conf, extack);
 }
 
 static int vxlan_changelink(struct net_device *dev, struct nlattr *tb[],
@@ -4700,40 +4700,6 @@ static struct rtnl_link_ops vxlan_link_ops __read_mostly = {
 	.get_link_net	= vxlan_get_link_net,
 };
 
-struct net_device *vxlan_dev_create(struct net *net, const char *name,
-				    u8 name_assign_type,
-				    struct vxlan_config *conf)
-{
-	struct nlattr *tb[IFLA_MAX + 1];
-	struct net_device *dev;
-	int err;
-
-	memset(&tb, 0, sizeof(tb));
-
-	dev = rtnl_create_link(net, name, name_assign_type,
-			       &vxlan_link_ops, tb, NULL);
-	if (IS_ERR(dev))
-		return dev;
-
-	err = __vxlan_dev_create(net, dev, conf, NULL);
-	if (err < 0) {
-		free_netdev(dev);
-		return ERR_PTR(err);
-	}
-
-	err = rtnl_configure_link(dev, NULL, 0, NULL);
-	if (err < 0) {
-		LIST_HEAD(list_kill);
-
-		vxlan_dellink(dev, &list_kill);
-		unregister_netdevice_many(&list_kill);
-		return ERR_PTR(err);
-	}
-
-	return dev;
-}
-EXPORT_SYMBOL_GPL(vxlan_dev_create);
-
 static void vxlan_handle_lowerdev_unregister(struct vxlan_net *vn,
 					     struct net_device *dev)
 {
diff --git a/include/net/vxlan.h b/include/net/vxlan.h
index 6e64757151b8..7b8207505523 100644
--- a/include/net/vxlan.h
+++ b/include/net/vxlan.h
@@ -359,9 +359,6 @@ struct vxlan_dev {
 					 VXLAN_F_MC_ROUTE          |	\
 					 0)
 
-struct net_device *vxlan_dev_create(struct net *net, const char *name,
-				    u8 name_assign_type, struct vxlan_config *conf);
-
 static inline netdev_features_t vxlan_features_check(struct sk_buff *skb,
 						     netdev_features_t features)
 {
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH net-next 0/6] openvswitch: remove support for legacy tunnel ports
  2026-08-04 18:20 [PATCH net-next 0/6] openvswitch: remove support for legacy tunnel ports Ilya Maximets
                   ` (5 preceding siblings ...)
  2026-08-04 18:20 ` [PATCH net-next 6/6] net: vxlan: remove unused vxlan_dev_create Ilya Maximets
@ 2026-08-06 11:03 ` Paolo Abeni
  2026-08-06 13:20 ` patchwork-bot+netdevbpf
  7 siblings, 0 replies; 9+ messages in thread
From: Paolo Abeni @ 2026-08-06 11:03 UTC (permalink / raw)
  To: Ilya Maximets, netdev
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Simon Horman, Aaron Conole, Eelco Chaudron, David Ahern,
	Ido Schimmel, Shuah Khan, Kuniyuki Iwashima, Nikolay Aleksandrov,
	Fernando Fernandez Mancera, Antoine Tenart, linux-kernel, dev,
	linux-kselftest

On 8/4/26 8:20 PM, Ilya Maximets wrote:
> ovs-vswitchd doesn't use OVS_VPORT_TYPE_GRE/VXLAN/GENEVE with the
> Linux kernel module since adding support for standard tunnel devices
> with COLLECT_METADATA back in 2017.  The code to use them was only
> activated as a fallback for old kernels, so not used in practice.  And
> it is now fully removed in the upcoming OVS 4.0 release.

Given the above, that ovs-vswitchd is the only legit user this interface
the change looks very safe to me...
>  21 files changed, 63 insertions(+), 874 deletions(-)

... and this is a very compelling reason to have it in ASAP.

/P


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH net-next 0/6] openvswitch: remove support for legacy tunnel ports
  2026-08-04 18:20 [PATCH net-next 0/6] openvswitch: remove support for legacy tunnel ports Ilya Maximets
                   ` (6 preceding siblings ...)
  2026-08-06 11:03 ` [PATCH net-next 0/6] openvswitch: remove support for legacy tunnel ports Paolo Abeni
@ 2026-08-06 13:20 ` patchwork-bot+netdevbpf
  7 siblings, 0 replies; 9+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-08-06 13:20 UTC (permalink / raw)
  To: Ilya Maximets
  Cc: netdev, andrew+netdev, davem, edumazet, kuba, pabeni, horms,
	aconole, echaudro, dsahern, idosch, shuah, kuniyu, razor,
	fmancera, atenart, linux-kernel, dev, linux-kselftest

Hello:

This series was applied to netdev/net-next.git (main)
by Paolo Abeni <pabeni@redhat.com>:

On Tue,  4 Aug 2026 20:20:34 +0200 you wrote:
> ovs-vswitchd doesn't use OVS_VPORT_TYPE_GRE/VXLAN/GENEVE with the
> Linux kernel module since adding support for standard tunnel devices
> with COLLECT_METADATA back in 2017.  The code to use them was only
> activated as a fallback for old kernels, so not used in practice.  And
> it is now fully removed in the upcoming OVS 4.0 release.
> 
> Modern way to use tunnels with OVS is to create standard tunnel ports
> with RTM_NEWLINK + COLLECT_METADATA and add them as OVS_VPORT_TYPE_NETDEV.
> 
> [...]

Here is the summary with links:
  - [net-next,1/6] openvswitch: remove support for legacy tunnel types
    https://git.kernel.org/netdev/net-next/c/d26dcf73a8f1
  - [net-next,2/6] openvswitch: vport: remove infrastructure for vport options
    https://git.kernel.org/netdev/net-next/c/38aecd1a1973
  - [net-next,3/6] openvswitch: vport: remove infrastructure for separate modules
    https://git.kernel.org/netdev/net-next/c/2425eba0f822
  - [net-next,4/6] net: geneve: remove unused geneve_dev_create_fb
    https://git.kernel.org/netdev/net-next/c/e5ba33295201
  - [net-next,5/6] net: gre: remove unused gretap_fb_dev_create
    https://git.kernel.org/netdev/net-next/c/9646825a51c4
  - [net-next,6/6] net: vxlan: remove unused vxlan_dev_create
    https://git.kernel.org/netdev/net-next/c/a5ae637f863d

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-08-06 13:21 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-04 18:20 [PATCH net-next 0/6] openvswitch: remove support for legacy tunnel ports Ilya Maximets
2026-08-04 18:20 ` [PATCH net-next 1/6] openvswitch: remove support for legacy tunnel types Ilya Maximets
2026-08-04 18:20 ` [PATCH net-next 2/6] openvswitch: vport: remove infrastructure for vport options Ilya Maximets
2026-08-04 18:20 ` [PATCH net-next 3/6] openvswitch: vport: remove infrastructure for separate modules Ilya Maximets
2026-08-04 18:20 ` [PATCH net-next 4/6] net: geneve: remove unused geneve_dev_create_fb Ilya Maximets
2026-08-04 18:20 ` [PATCH net-next 5/6] net: gre: remove unused gretap_fb_dev_create Ilya Maximets
2026-08-04 18:20 ` [PATCH net-next 6/6] net: vxlan: remove unused vxlan_dev_create Ilya Maximets
2026-08-06 11:03 ` [PATCH net-next 0/6] openvswitch: remove support for legacy tunnel ports Paolo Abeni
2026-08-06 13:20 ` patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox