Netdev List
 help / color / mirror / Atom feed
* [RFC net-next 0/6] openvswitch: remove support for legacy tunnel ports
@ 2026-05-13 18:35 Ilya Maximets
  2026-05-13 18:35 ` [RFC net-next 1/6] openvswitch: remove support for legacy tunnel types Ilya Maximets
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Ilya Maximets @ 2026-05-13 18:35 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, Nikolay Aleksandrov,
	Kuniyuki Iwashima, Petr Machata, Fernando Fernandez Mancera,
	Antoine Tenart, Stanislav Fomichev, linux-kernel, dev,
	linux-kselftest, Ilya Maximets

ovs-vswitchd doesn't use OVS_VPORT_TYPE_GRE/VXLAN/GENEVE with upstream
Linux kernel module since adding support for standard tunnel devices
with COLLECT_METADATA back in 2017.  The code to use them is still
present, but it is only activated as a fallback for old kernels, so
not used in practice.  And it is marked for removal in the next OVS
release this summer.  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 recently.  Since
there are no actual users for these port types for a very long time,
let's just remove the support entirely.


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.  It may technically
   be used by some out-of-tree module, but it is unlikely, so the
   proposal here is to also just remove it.  Or we can consider
   deprecation.  It's not really a user API, it's an API for modules.
   Which can be considered as users, I guess.  Not sure.

3. Patches 4-6 remove functions from gre/vxlan/geneve modules that
   were added for openvswitch in the past to support the tunnel types.
   And openvswitch is the only in-tree consumer of these functions,
   so we could remove them.  But they are also exported symbols, so
   can in theory be used by some out-of-tree modules, though I doubt
   that.  Not sure what the process should be here.  Removal seems
   reasonable, but we may consider deprecation first.

Thoughts?


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                          |  48 -----
 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                    |  22 +--
 net/openvswitch/vport-geneve.c                | 143 ---------------
 net/openvswitch/vport-gre.c                   | 106 -----------
 net/openvswitch/vport-netdev.c                |  28 +--
 net/openvswitch/vport-netdev.h                |   3 +-
 net/openvswitch/vport-vxlan.c                 | 172 ------------------
 net/openvswitch/vport.c                       |  76 +-------
 net/openvswitch/vport.h                       |  23 +--
 tools/testing/selftests/net/config            |   3 -
 .../selftests/net/openvswitch/openvswitch.sh  |  37 ----
 .../selftests/net/openvswitch/ovs-dpctl.py    |  93 +++-------
 20 files changed, 59 insertions(+), 864 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.53.0


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

* [RFC net-next 1/6] openvswitch: remove support for legacy tunnel types
  2026-05-13 18:35 [RFC net-next 0/6] openvswitch: remove support for legacy tunnel ports Ilya Maximets
@ 2026-05-13 18:35 ` Ilya Maximets
  2026-05-13 18:35 ` [RFC net-next 2/6] openvswitch: vport: remove infrastructure for vport options Ilya Maximets
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Ilya Maximets @ 2026-05-13 18:35 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, Nikolay Aleksandrov,
	Kuniyuki Iwashima, Petr Machata, Fernando Fernandez Mancera,
	Antoine Tenart, Stanislav Fomichev, linux-kernel, dev,
	linux-kselftest, Ilya Maximets

ovs-vswitchd doesn't use OVS_VPORT_TYPE_GRE/VXLAN/GENEVE with upstream
Linux kernel module since adding support for standard tunnel devices
with COLLECT_METADATA back in 2017.  The code to use them is still
present, but it is only activated as a fallback for old kernels, so
not used in practice.  And it is marked for removal in the next OVS
release this summer.

Device reference management and the netlink options parsing for these
port types is complicated and was a CVE magnet recently.  Since there
are no actual users for these port types for a very long time, let's
just remove the support entirely.

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                |  28 +--
 net/openvswitch/vport-netdev.h                |   3 +-
 net/openvswitch/vport-vxlan.c                 | 172 ------------------
 tools/testing/selftests/net/config            |   3 -
 .../selftests/net/openvswitch/openvswitch.sh  |  37 ----
 .../selftests/net/openvswitch/ovs-dpctl.py    |  93 +++-------
 12 files changed, 53 insertions(+), 608 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 aa2acdbda8f89..440825e658371 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 e6aaee92dba48..19ac9ae18f1e7 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 28982630bef32..46a27ab369f90 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 bbbde50fc6498..d86c53fedc1e1 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -2206,11 +2206,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 cb5ea4424ffc8..0000000000000
--- 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 6cb5a697b396a..0000000000000
--- 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 c42642075685d..ebfee309e6dbb 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)
+struct vport *ovs_netdev_link(struct vport *vport)
 {
 	int err;
 
@@ -104,8 +104,6 @@ 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:
@@ -144,7 +142,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:
@@ -196,28 +194,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 6c0d7366f9862..15fa27054b505 100644
--- a/net/openvswitch/vport-netdev.h
+++ b/net/openvswitch/vport-netdev.h
@@ -13,11 +13,10 @@
 
 struct vport *ovs_netdev_get_vport(struct net_device *dev);
 
-struct vport *ovs_netdev_link(struct vport *vport, bool tunnel);
+struct vport *ovs_netdev_link(struct vport *vport);
 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 c1b37b50d29e1..0000000000000
--- 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 d07c5ac5cab7b..5e9ccc897a360 100644
--- a/tools/testing/selftests/net/config
+++ b/tools/testing/selftests/net/config
@@ -114,9 +114,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/openvswitch.sh b/tools/testing/selftests/net/openvswitch/openvswitch.sh
index 3cdd953f68132..b327d3061ed53 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
 	psample					psample: Sampling packets with psample"
 
@@ -831,42 +830,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
-}
-
 run_test() {
 	(
 	tname="$1"
diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
index bbe35e2718d26..ad8c47a482351 100644
--- a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
+++ b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py
@@ -2012,9 +2012,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 = (
@@ -2022,7 +2019,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"),
@@ -2030,13 +2027,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"),
@@ -2054,25 +2044,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()):
@@ -2105,16 +2083,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]]
         )
@@ -2128,36 +2108,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(
@@ -2565,19 +2530,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,
                 )
             )
 
@@ -2649,13 +2607,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")
@@ -2729,7 +2680,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.53.0


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

* [RFC net-next 2/6] openvswitch: vport: remove infrastructure for vport options
  2026-05-13 18:35 [RFC net-next 0/6] openvswitch: remove support for legacy tunnel ports Ilya Maximets
  2026-05-13 18:35 ` [RFC net-next 1/6] openvswitch: remove support for legacy tunnel types Ilya Maximets
@ 2026-05-13 18:35 ` Ilya Maximets
  2026-05-13 18:35 ` [RFC net-next 3/6] openvswitch: vport: remove infrastructure for separate modules Ilya Maximets
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Ilya Maximets @ 2026-05-13 18:35 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, Nikolay Aleksandrov,
	Kuniyuki Iwashima, Petr Machata, Fernando Fernandez Mancera,
	Antoine Tenart, Stanislav Fomichev, 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.

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.  Alternative to
immediate removal would be printing out a deprecation warning whenever
the options setting is attempted.

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, 1 insertion(+), 87 deletions(-)

diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index d86c53fedc1e1..a9c0cc2c702a4 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -1852,7 +1852,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];
@@ -2168,10 +2167,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;
 
@@ -2179,7 +2174,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;
 }
@@ -2206,10 +2200,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;
 }
 
@@ -2361,7 +2351,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];
@@ -2422,13 +2411,6 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info)
 		goto exit_unlock_free;
 	}
 
-	if (a[OVS_VPORT_ATTR_OPTIONS]) {
-		err = ovs_vport_set_options(vport, a[OVS_VPORT_ATTR_OPTIONS]);
-		if (err)
-			goto exit_unlock_free;
-	}
-
-
 	if (a[OVS_VPORT_ATTR_UPCALL_PID]) {
 		struct nlattr *ids = a[OVS_VPORT_ATTR_UPCALL_PID];
 
@@ -2602,7 +2584,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 56b2e2d1a749f..7a9caacfd6ac2 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 9f67b9dd49f98..636788b59907c 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.53.0


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

* [RFC net-next 3/6] openvswitch: vport: remove infrastructure for separate modules
  2026-05-13 18:35 [RFC net-next 0/6] openvswitch: remove support for legacy tunnel ports Ilya Maximets
  2026-05-13 18:35 ` [RFC net-next 1/6] openvswitch: remove support for legacy tunnel types Ilya Maximets
  2026-05-13 18:35 ` [RFC net-next 2/6] openvswitch: vport: remove infrastructure for vport options Ilya Maximets
@ 2026-05-13 18:35 ` Ilya Maximets
  2026-05-13 18:35 ` [RFC net-next 4/6] net: geneve: remove unused geneve_dev_create_fb Ilya Maximets
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Ilya Maximets @ 2026-05-13 18:35 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, Nikolay Aleksandrov,
	Kuniyuki Iwashima, Petr Machata, Fernando Fernandez Mancera,
	Antoine Tenart, Stanislav Fomichev, 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.
Alternative to immediate removal would be printing out a deprecation
warning whenever a vport module is loaded, but I'm not sure if we
need it at this time.

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

diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c
index 7a9caacfd6ac2..ef2fff4353c0a 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,12 +208,8 @@ 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);
 			return vport;
 		}
 
@@ -225,18 +219,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 +233,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 636788b59907c..930f1ccc85581 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.53.0


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

* [RFC net-next 4/6] net: geneve: remove unused geneve_dev_create_fb
  2026-05-13 18:35 [RFC net-next 0/6] openvswitch: remove support for legacy tunnel ports Ilya Maximets
                   ` (2 preceding siblings ...)
  2026-05-13 18:35 ` [RFC net-next 3/6] openvswitch: vport: remove infrastructure for separate modules Ilya Maximets
@ 2026-05-13 18:35 ` Ilya Maximets
  2026-05-13 18:35 ` [RFC net-next 5/6] net: gre: remove unused gretap_fb_dev_create Ilya Maximets
  2026-05-13 18:35 ` [RFC net-next 6/6] net: vxlan: remove unused vxlan_dev_create Ilya Maximets
  5 siblings, 0 replies; 7+ messages in thread
From: Ilya Maximets @ 2026-05-13 18:35 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, Nikolay Aleksandrov,
	Kuniyuki Iwashima, Petr Machata, Fernando Fernandez Mancera,
	Antoine Tenart, Stanislav Fomichev, linux-kernel, dev,
	linux-kselftest, Ilya Maximets

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

Note: since it's an exported symbol, there is a possibility that some
out-of-tree module is using it.  So, alternative is to deprecate it
instead by adding a warning if it is ever called.

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

diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
index b36fad8337245..153b15e4ef569 100644
--- a/drivers/net/geneve.c
+++ b/drivers/net/geneve.c
@@ -2364,54 +2364,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,
-		.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 5c96827a487e7..ba2c14d61e904 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.53.0


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

* [RFC net-next 5/6] net: gre: remove unused gretap_fb_dev_create
  2026-05-13 18:35 [RFC net-next 0/6] openvswitch: remove support for legacy tunnel ports Ilya Maximets
                   ` (3 preceding siblings ...)
  2026-05-13 18:35 ` [RFC net-next 4/6] net: geneve: remove unused geneve_dev_create_fb Ilya Maximets
@ 2026-05-13 18:35 ` Ilya Maximets
  2026-05-13 18:35 ` [RFC net-next 6/6] net: vxlan: remove unused vxlan_dev_create Ilya Maximets
  5 siblings, 0 replies; 7+ messages in thread
From: Ilya Maximets @ 2026-05-13 18:35 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, Nikolay Aleksandrov,
	Kuniyuki Iwashima, Petr Machata, Fernando Fernandez Mancera,
	Antoine Tenart, Stanislav Fomichev, linux-kernel, dev,
	linux-kselftest, Ilya Maximets

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

Note: since it's an exported symbol, there is a possibility that some
out-of-tree module is using it.  So, alternative is to deprecate it
instead by adding a warning if it is ever called.

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 ccd2932032844..b55f67ecd2fc4 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 169e2921a851d..a1dd833ea1cad 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -1710,53 +1710,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.53.0


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

* [RFC net-next 6/6] net: vxlan: remove unused vxlan_dev_create
  2026-05-13 18:35 [RFC net-next 0/6] openvswitch: remove support for legacy tunnel ports Ilya Maximets
                   ` (4 preceding siblings ...)
  2026-05-13 18:35 ` [RFC net-next 5/6] net: gre: remove unused gretap_fb_dev_create Ilya Maximets
@ 2026-05-13 18:35 ` Ilya Maximets
  5 siblings, 0 replies; 7+ messages in thread
From: Ilya Maximets @ 2026-05-13 18:35 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, Nikolay Aleksandrov,
	Kuniyuki Iwashima, Petr Machata, Fernando Fernandez Mancera,
	Antoine Tenart, Stanislav Fomichev, 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.

Note: since it's an exported symbol, there is a possibility that some
out-of-tree module is using it.  So, alternative is to deprecate it
instead by adding a warning if it is ever called.

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 00facbfabced4..a3e9608095685 100644
--- a/drivers/net/vxlan/vxlan_core.c
+++ b/drivers/net/vxlan/vxlan_core.c
@@ -3958,9 +3958,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);
@@ -4408,7 +4408,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[],
@@ -4689,40 +4689,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 dfba89695efcf..7db2c9dd67e79 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.53.0


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

end of thread, other threads:[~2026-05-13 18:36 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-13 18:35 [RFC net-next 0/6] openvswitch: remove support for legacy tunnel ports Ilya Maximets
2026-05-13 18:35 ` [RFC net-next 1/6] openvswitch: remove support for legacy tunnel types Ilya Maximets
2026-05-13 18:35 ` [RFC net-next 2/6] openvswitch: vport: remove infrastructure for vport options Ilya Maximets
2026-05-13 18:35 ` [RFC net-next 3/6] openvswitch: vport: remove infrastructure for separate modules Ilya Maximets
2026-05-13 18:35 ` [RFC net-next 4/6] net: geneve: remove unused geneve_dev_create_fb Ilya Maximets
2026-05-13 18:35 ` [RFC net-next 5/6] net: gre: remove unused gretap_fb_dev_create Ilya Maximets
2026-05-13 18:35 ` [RFC net-next 6/6] net: vxlan: remove unused vxlan_dev_create Ilya Maximets

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