public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
From: Ralf Lici <ralf@mandelbit.com>
To: netdev@vger.kernel.org
Cc: "Daniel Gröber" <dxld@darkboxed.org>,
	"Ralf Lici" <ralf@mandelbit.com>,
	"Antonio Quartulli" <antonio@mandelbit.com>,
	"Andrew Lunn" <andrew+netdev@lunn.ch>,
	"David S. Miller" <davem@davemloft.net>,
	"Eric Dumazet" <edumazet@google.com>,
	"Jakub Kicinski" <kuba@kernel.org>,
	"Paolo Abeni" <pabeni@redhat.com>,
	linux-kernel@vger.kernel.org
Subject: [RFC net-next 01/15] drivers/net: add ipxlat netdevice skeleton and build plumbing
Date: Thu, 19 Mar 2026 16:12:10 +0100	[thread overview]
Message-ID: <20260319151230.655687-2-ralf@mandelbit.com> (raw)
In-Reply-To: <20260319151230.655687-1-ralf@mandelbit.com>

ipxlat is a virtual netdevice implementing stateless IPv4/IPv6
translation (SIIT). The translation model follows RFC 7915 behavior and
RFC 6052 address embedding rules.

The netdevice form is intentional: it provides per-instance lifecycle,
MTU/statistics semantics and explicit routing integration, so translated
traffic can be steered through a dedicated device and configured per
namespace.

This series targets ipxlat as a reusable kernel building block for SIIT
deployments and for NAT64-style setups when combined with existing
nftables rules in userspace policy.

This first patch introduces only the driver scaffolding:
- drivers/net/ipxlat/ directory and build integration
- Kconfig/Makefile entries
- basic private structures and defaults
- rtnl_link_ops and netdevice skeleton needed to create/register links

No translation logic is added in this patch yet. Follow-up patches add
packet validation, transport/ICMP translation, error handling,
fragmentation handling, generic netlink control plane, selftests and
documentation.

Signed-off-by: Ralf Lici <ralf@mandelbit.com>
---
 drivers/net/Kconfig           |  13 ++++
 drivers/net/Makefile          |   1 +
 drivers/net/ipxlat/Makefile   |   7 ++
 drivers/net/ipxlat/ipxlpriv.h |  53 +++++++++++++
 drivers/net/ipxlat/main.c     | 137 ++++++++++++++++++++++++++++++++++
 drivers/net/ipxlat/main.h     |  27 +++++++
 6 files changed, 238 insertions(+)
 create mode 100644 drivers/net/ipxlat/Makefile
 create mode 100644 drivers/net/ipxlat/ipxlpriv.h
 create mode 100644 drivers/net/ipxlat/main.c
 create mode 100644 drivers/net/ipxlat/main.h

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index b2fd90466bab..a3b28f294d95 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -117,6 +117,19 @@ config OVPN
 	  This module enhances the performance of the OpenVPN userspace software
 	  by offloading the data channel processing to kernelspace.
 
+config IPXLAT
+	tristate "IPv6<>IPv4 packet translation virtual device (SIIT)"
+	depends on NET && INET && IPV6
+	help
+	  Virtual network device driver for Stateless IP/ICMP Packet
+	  Translation (RFC 7915). Useful for IPv6 focused networks.
+	  Particularly NAT64, SIIT-DC, 464XLAT network architectures.
+
+	  See also <file:Documentation/networking/ipxlat.rst>.
+
+	  To compile this driver as a module, choose M here: the module will be
+	  called ipxlat.
+
 config EQUALIZER
 	tristate "EQL (serial line load balancing) support"
 	help
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 5b01215f6829..4f982c9e6585 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_NET) += loopback.o
 obj-$(CONFIG_NETDEV_LEGACY_INIT) += Space.o
 obj-$(CONFIG_NETCONSOLE) += netconsole.o
 obj-$(CONFIG_NETKIT) += netkit.o
+obj-$(CONFIG_IPXLAT) += ipxlat/
 obj-y += phy/
 obj-y += pse-pd/
 obj-y += mdio/
diff --git a/drivers/net/ipxlat/Makefile b/drivers/net/ipxlat/Makefile
new file mode 100644
index 000000000000..bd48c2700bf5
--- /dev/null
+++ b/drivers/net/ipxlat/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# IPXLAT - Stateless IP/ICMP Translation (SIIT) virtual device driver
+
+obj-$(CONFIG_IPXLAT) := ipxlat.o
+
+ipxlat-objs += main.o
diff --git a/drivers/net/ipxlat/ipxlpriv.h b/drivers/net/ipxlat/ipxlpriv.h
new file mode 100644
index 000000000000..5027d8377bdd
--- /dev/null
+++ b/drivers/net/ipxlat/ipxlpriv.h
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*  IPXLAT - Stateless IP/ICMP Translation (SIIT) virtual device driver
+ *
+ *  Copyright (C) 2024- Alberto Leiva Popper <ydahhrk@gmail.com>
+ *  Copyright (C) 2026- Mandelbit SRL
+ *  Copyright (C) 2026- Daniel Gröber <dxld@darkboxed.org>
+ *
+ *  Author:	Alberto Leiva Popper <ydahhrk@gmail.com>
+ *		Antonio Quartulli <antonio@mandelbit.com>
+ *		Daniel Gröber <dxld@darkboxed.org>
+ *		Ralf Lici <ralf@mandelbit.com>
+ */
+
+#ifndef _NET_IPXLAT_IPXLPRIV_H_
+#define _NET_IPXLAT_IPXLPRIV_H_
+
+#include <linux/mutex.h>
+#include <linux/netdevice.h>
+#include <net/gro_cells.h>
+
+/**
+ * struct ipv6_prefix - IPv6 prefix definition
+ * @addr: prefix address (host bits may be non-zero)
+ * @len: prefix length in bits
+ */
+struct ipv6_prefix {
+	struct in6_addr addr;
+	u8 len;
+};
+
+/**
+ * struct ipxlat_priv - private state stored in netdev priv area
+ * @dev: owning netdevice
+ * @xlat_prefix6: RFC 6052 prefix used for stateless v4<->v6 mapping
+ * @lowest_ipv6_mtu: LIM threshold used by 4->6 pre-fragment planning
+ * @cfg_lock: serializes control-plane updates
+ * @gro_cells: receive-side reinjection queue used by forward path
+ *
+ * Datapath reads config without taking @cfg_lock to keep per-packet overhead
+ * low. Writers serialize updates under @cfg_lock. During reconfiguration,
+ * readers may transiently observe mixed old/new values; this may cause a small
+ * number of drops and is an accepted tradeoff for a lightweight datapath.
+ */
+struct ipxlat_priv {
+	struct net_device *dev;
+	struct ipv6_prefix xlat_prefix6;
+	u32 lowest_ipv6_mtu;
+	/* serializes control-plane updates */
+	struct mutex cfg_lock;
+	struct gro_cells gro_cells;
+};
+
+#endif /* _NET_IPXLAT_IPXLPRIV_H_ */
diff --git a/drivers/net/ipxlat/main.c b/drivers/net/ipxlat/main.c
new file mode 100644
index 000000000000..26b7f5b6ff20
--- /dev/null
+++ b/drivers/net/ipxlat/main.c
@@ -0,0 +1,137 @@
+// SPDX-License-Identifier: GPL-2.0
+/*  IPXLAT - Stateless IP/ICMP Translation (SIIT) virtual device driver
+ *
+ *  Copyright (C) 2024- Alberto Leiva Popper <ydahhrk@gmail.com>
+ *  Copyright (C) 2026- Mandelbit SRL
+ *  Copyright (C) 2026- Daniel Gröber <dxld@darkboxed.org>
+ *
+ *  Author:	Alberto Leiva Popper <ydahhrk@gmail.com>
+ *		Antonio Quartulli <antonio@mandelbit.com>
+ *		Daniel Gröber <dxld@darkboxed.org>
+ *		Ralf Lici <ralf@mandelbit.com>
+ */
+
+#include <linux/module.h>
+
+#include <net/ip.h>
+
+#include "ipxlpriv.h"
+#include "main.h"
+
+MODULE_AUTHOR("Alberto Leiva Popper <ydahhrk@gmail.com>");
+MODULE_AUTHOR("Antonio Quartulli <antonio@mandelbit.com>");
+MODULE_AUTHOR("Daniel Gröber <dxld@darkboxed.org>");
+MODULE_AUTHOR("Ralf Lici <ralf@mandelbit.com>");
+MODULE_DESCRIPTION("IPv6<>IPv4 translation virtual netdev support (SIIT)");
+MODULE_LICENSE("GPL");
+
+static int ipxlat_dev_init(struct net_device *dev)
+{
+	struct ipxlat_priv *ipxlat = netdev_priv(dev);
+	int err;
+
+	ipxlat->dev = dev;
+	/* default xlat-prefix6 is 64:ff9b::/96 */
+	ipxlat->xlat_prefix6.addr.s6_addr32[0] = htonl(0x0064ff9b);
+	ipxlat->xlat_prefix6.addr.s6_addr32[1] = 0;
+	ipxlat->xlat_prefix6.addr.s6_addr32[2] = 0;
+	ipxlat->xlat_prefix6.addr.s6_addr32[3] = 0;
+	ipxlat->xlat_prefix6.len = 96;
+	ipxlat->lowest_ipv6_mtu = 1280;
+	mutex_init(&ipxlat->cfg_lock);
+
+	err = gro_cells_init(&ipxlat->gro_cells, dev);
+	if (unlikely(err))
+		return err;
+
+	return 0;
+}
+
+static void ipxlat_dev_uninit(struct net_device *dev)
+{
+	struct ipxlat_priv *ipxlat = netdev_priv(dev);
+
+	gro_cells_destroy(&ipxlat->gro_cells);
+}
+
+static int ipxlat_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	dev_dstats_tx_dropped(dev);
+	kfree_skb(skb);
+	return NETDEV_TX_OK;
+}
+
+static const struct net_device_ops ipxlat_netdev_ops = {
+	.ndo_init = ipxlat_dev_init,
+	.ndo_uninit = ipxlat_dev_uninit,
+	.ndo_start_xmit = ipxlat_start_xmit,
+};
+
+static const struct device_type ipxlat_type = {
+	.name = "ipxlat",
+};
+
+static void ipxlat_setup(struct net_device *dev)
+{
+	const netdev_features_t feat = NETIF_F_SG | NETIF_F_FRAGLIST |
+				       NETIF_F_HW_CSUM | NETIF_F_HIGHDMA |
+				       NETIF_F_GSO_SOFTWARE;
+
+	dev->type = ARPHRD_NONE;
+	dev->flags = IFF_NOARP;
+	dev->priv_flags |= IFF_NO_QUEUE;
+	dev->hard_header_len = 0;
+	dev->addr_len = 0;
+
+	dev->lltx = true;
+	dev->features |= feat;
+	dev->hw_features |= feat;
+	dev->hw_enc_features |= feat;
+
+	dev->netdev_ops = &ipxlat_netdev_ops;
+	dev->needs_free_netdev = true;
+	dev->pcpu_stat_type = NETDEV_PCPU_STAT_DSTATS;
+	dev->max_mtu = IP_MAX_MTU - sizeof(struct ipv6hdr) -
+		       sizeof(struct iphdr);
+	dev->min_mtu = IPV6_MIN_MTU;
+	dev->mtu = ETH_DATA_LEN;
+
+	/* keep skb->dst up to ndo_start_xmit so ICMP error emission can
+	 * reuse routing metadata from ingress when available
+	 */
+	netif_keep_dst(dev);
+
+	SET_NETDEV_DEVTYPE(dev, &ipxlat_type);
+}
+
+static struct rtnl_link_ops ipxlat_link_ops = {
+	.kind = "ipxlat",
+	.priv_size = sizeof(struct ipxlat_priv),
+	.setup = ipxlat_setup,
+};
+
+bool ipxlat_dev_is_valid(const struct net_device *dev)
+{
+	return dev->rtnl_link_ops == &ipxlat_link_ops;
+}
+
+static int __init ipxlat_init(void)
+{
+	int err;
+
+	err = rtnl_link_register(&ipxlat_link_ops);
+	if (err) {
+		pr_err("ipxlat: failed to register rtnl link ops: %d\n", err);
+		return err;
+	}
+
+	return 0;
+}
+
+static void __exit ipxlat_exit(void)
+{
+	rtnl_link_unregister(&ipxlat_link_ops);
+}
+
+module_init(ipxlat_init);
+module_exit(ipxlat_exit);
diff --git a/drivers/net/ipxlat/main.h b/drivers/net/ipxlat/main.h
new file mode 100644
index 000000000000..fb78f910b2e2
--- /dev/null
+++ b/drivers/net/ipxlat/main.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*  IPXLAT - Stateless IP/ICMP Translation (SIIT) virtual device driver
+ *
+ *  Copyright (C) 2024- Alberto Leiva Popper <ydahhrk@gmail.com>
+ *  Copyright (C) 2026- Mandelbit SRL
+ *  Copyright (C) 2026- Daniel Gröber <dxld@darkboxed.org>
+ *
+ *  Author:	Alberto Leiva Popper <ydahhrk@gmail.com>
+ *		Antonio Quartulli <antonio@mandelbit.com>
+ *		Daniel Gröber <dxld@darkboxed.org>
+ *		Ralf Lici <ralf@mandelbit.com>
+ */
+
+#ifndef _NET_IPXLAT_MAIN_H_
+#define _NET_IPXLAT_MAIN_H_
+
+#include <linux/netdevice.h>
+
+/**
+ * ipxlat_dev_is_valid - tell whether a netdev is an ipxlat interface
+ * @dev: netdevice to inspect
+ *
+ * Return: true if @dev was created with ipxlat link ops.
+ */
+bool ipxlat_dev_is_valid(const struct net_device *dev);
+
+#endif /* _NET_IPXLAT_MAIN_H_ */
-- 
2.53.0


  reply	other threads:[~2026-03-19 15:19 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-19 15:12 [RFC net-next 00/15] Introducing ipxlat: a stateless IPv4/IPv6 translation device Ralf Lici
2026-03-19 15:12 ` Ralf Lici [this message]
2026-03-19 15:12 ` [RFC net-next 02/15] ipxlat: add RFC 6052 address conversion helpers Ralf Lici
2026-03-19 15:12 ` [RFC net-next 03/15] ipxlat: add packet metadata control block helpers Ralf Lici
2026-03-19 15:12 ` [RFC net-next 04/15] ipxlat: add IPv4 packet validation path Ralf Lici
2026-03-19 15:12 ` [RFC net-next 05/15] ipxlat: add IPv6 " Ralf Lici
2026-03-19 15:12 ` [RFC net-next 06/15] ipxlat: add transport checksum and offload helpers Ralf Lici
2026-03-19 15:12 ` [RFC net-next 07/15] ipxlat: add 4to6 and 6to4 TCP/UDP translation helpers Ralf Lici
2026-03-19 15:12 ` [RFC net-next 08/15] ipxlat: add translation engine and dispatch core Ralf Lici
2026-03-19 15:12 ` [RFC net-next 09/15] ipxlat: emit translator-generated ICMP errors on drop Ralf Lici
2026-03-19 15:12 ` [RFC net-next 10/15] ipxlat: add 4to6 pre-fragmentation path Ralf Lici
2026-03-19 15:12 ` [RFC net-next 11/15] ipxlat: add ICMP informational translation paths Ralf Lici
2026-03-19 15:12 ` [RFC net-next 12/15] ipxlat: add ICMP error translation and quoted-inner handling Ralf Lici
2026-03-19 15:12 ` [RFC net-next 13/15] ipxlat: add netlink control plane and uapi Ralf Lici
2026-03-19 15:12 ` [RFC net-next 14/15] selftests: net: add ipxlat coverage Ralf Lici
2026-03-19 15:12 ` [RFC net-next 15/15] Documentation: networking: add ipxlat translator guide Ralf Lici
2026-03-19 22:11   ` Jonathan Corbet
2026-03-24  9:55     ` Ralf Lici

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=20260319151230.655687-2-ralf@mandelbit.com \
    --to=ralf@mandelbit.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=antonio@mandelbit.com \
    --cc=davem@davemloft.net \
    --cc=dxld@darkboxed.org \
    --cc=edumazet@google.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    /path/to/YOUR_REPLY

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

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