All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ralf Lici <ralf@mandelbit.com>
To: netdev@vger.kernel.org
Cc: "David Ahern" <dsahern@kernel.org>,
	"Ido Schimmel" <idosch@nvidia.com>,
	"David S. Miller" <davem@davemloft.net>,
	"Eric Dumazet" <edumazet@kernel.org>,
	"Jakub Kicinski" <kuba@kernel.org>,
	"Paolo Abeni" <pabeni@redhat.com>,
	"Simon Horman" <horms@kernel.org>,
	"Daniel Gröber" <dxld@darkboxed.org>,
	"Antonio Quartulli" <antonio@mandelbit.com>,
	"Toke Høiland-Jørgensen" <toke@kernel.org>,
	linux-kernel@vger.kernel.org
Subject: [RFC net-next v2 12/18] net: ipxlat: add translation preparation and dispatch
Date: Sat, 24 Oct 2026 11:25:22 +0200	[thread overview]
Message-ID: <20261024092532.172005-13-ralf@mandelbit.com> (raw)
In-Reply-To: <20261024092532.172005-1-ralf@mandelbit.com>

Expose a two-stage engine interface which validates and caches packet
metadata before rewriting. Mark translated DF-clear IPv4 packets so
IPv6 output owns any required fragmentation or refragmentation.

Signed-off-by: Ralf Lici <ralf@mandelbit.com>
---
Changes since RFC v1 https://lore.kernel.org/netdev/20260319151230.655687-9-ralf@mandelbit.com/
- Replace the v1 ndo_start_xmit dispatch/actions with the exported
  ipxlat_prepare and ipxlat_translate engine interface so attachments
  other than the initial LWT harness can reuse the translator. (Toke)
- Complete eligibility checks and protocol preflight before mutation so
  unsupported packets can be returned untouched. Allocation failures
  during the rewrite still leave the packet for the caller to discard.
- Stop decrementing TTL or Hop Limit inside the engine: the
  translated-family forwarding path owns the one forwarding decrement.
  (Sashiko)
- Remove pre-fragmentation and mark translated DF-clear IPv4
  representations for fragmentation by the target IPv6 output route.

 include/net/ipxlat.h | 35 +++++++++++++++++
 net/ipxlat/core.c    | 92 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 127 insertions(+)

diff --git a/include/net/ipxlat.h b/include/net/ipxlat.h
index 6b8efb2669b8..ddc98058ff20 100644
--- a/include/net/ipxlat.h
+++ b/include/net/ipxlat.h
@@ -16,6 +16,7 @@
 
 #include <linux/in6.h>
 #include <linux/types.h>
+#include <net/ip.h>
 
 struct ipxlat_prefix4 {
 	__be32 addr;
@@ -63,4 +64,38 @@ bool ipxlat_prefix6_len_valid(u8 len);
  */
 int ipxlat_config_validate(const struct ipxlat_config *cfg);
 
+/**
+ * ipxlat_prepare - validate a packet and cache translation metadata
+ * @cfg: validated, immutable translation configuration
+ * @skb: packet to prepare
+ *
+ * The caller must own @skb exclusively. This function uses @skb->cb as parser
+ * storage but does not rewrite packet bytes. On success it sets the transport
+ * header offset. %-EOPNOTSUPP means ipxlat does not handle the packet. A caller
+ * that passes such a packet back to the original stack must restore the old
+ * control buffer.
+ *
+ * Return: 0 when @skb is ready for ipxlat_translate, or a negative errno.
+ */
+int ipxlat_prepare(const struct ipxlat_config *cfg, struct sk_buff *skb);
+
+/**
+ * ipxlat_translate - translate one prepared skb without consuming it
+ * @cfg: configuration used by the preceding ipxlat_prepare call
+ * @net: namespace in which translation runs and whose IPv4 ID state is used
+ * @skb: prepared packet to translate
+ *
+ * The caller must provide a non-NULL @net and must not change @cfg, @skb or
+ * its cached metadata between preparation and translation. Successful
+ * Translation of a DF-clear IPv4 packet sets @skb->ignore_df and marks the
+ * resulting IPv6 packet as locally owned for target-family fragmentation. A
+ * harness which scrubs the skb must preserve both properties.
+ *
+ * Return: 0 with @skb in the translated representation, or a negative errno
+ * with the packet representation unspecified, in which case the caller must
+ * discard it.
+ */
+int ipxlat_translate(const struct ipxlat_config *cfg, struct net *net,
+		     struct sk_buff *skb);
+
 #endif /* _NET_IPXLAT_H_ */
diff --git a/net/ipxlat/core.c b/net/ipxlat/core.c
index 85037446291e..1dc1fc7e6f04 100644
--- a/net/ipxlat/core.c
+++ b/net/ipxlat/core.c
@@ -12,6 +12,98 @@
  */
 
 #include <linux/module.h>
+#include <net/ip.h>
+#include <net/ipv6.h>
+
+#include <net/ipxlat.h>
+#include "address.h"
+#include "packet.h"
+#include "translate_46.h"
+#include "translate_64.h"
+
+int ipxlat_prepare(const struct ipxlat_config *cfg, struct sk_buff *skb)
+{
+	struct ipxlat_cb *cb = ipxlat_skb_cb(skb);
+	int ret;
+
+	DEBUG_NET_WARN_ON_ONCE(skb_shared(skb));
+	memset(skb->cb, 0, sizeof(struct ipxlat_cb));
+
+	switch (ntohs(skb->protocol)) {
+	case ETH_P_IPV6:
+		ret = ipxlat_v6_validate_skb(skb);
+		if (unlikely(ret))
+			return ret;
+
+		/* packets with non-translatable IPv6 addresses can be handed
+		 * back to the stack unchanged since they might be intended for
+		 * native traffic such as ND
+		 */
+		ret = ipxlat_64_convert_endpoints(cfg, ipv6_hdr(skb),
+						  cb->is_icmp_err, &cb->saddr4,
+						  &cb->daddr4);
+		if (unlikely(ret))
+			return -EOPNOTSUPP;
+
+		if (unlikely(cb->l4_proto == NEXTHDR_ICMP))
+			return -EOPNOTSUPP;
+		break;
+	case ETH_P_IP:
+		ret = ipxlat_v4_validate_skb(skb);
+		if (unlikely(ret))
+			return ret;
+
+		if (unlikely(cb->l4_proto == IPPROTO_ICMP))
+			return -EOPNOTSUPP;
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	skb_set_transport_header(skb, cb->l4_off);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(ipxlat_prepare);
+
+int ipxlat_translate(const struct ipxlat_config *cfg, struct net *net,
+		     struct sk_buff *skb)
+{
+	bool frag_source;
+	int ret;
+
+	switch (ntohs(skb->protocol)) {
+	case ETH_P_IPV6:
+		return ipxlat_64_translate(cfg, net, skb);
+	case ETH_P_IP:
+		frag_source = !(ip_hdr(skb)->frag_off & htons(IP_DF));
+
+		if (ipxlat_skb_cb(skb)->l4_proto == IPPROTO_UDP) {
+			/* calculate the csum of a csumless UDP packet */
+			ret = ipxlat_46_prepare_udp_csum(skb);
+			if (unlikely(ret))
+				return ret;
+		}
+
+		ret = ipxlat_46_translate(cfg, skb);
+		if (unlikely(ret))
+			return ret;
+
+		/* Replace parser state with IPv6 fragmentation metadata.
+		 * DF-clear IPv4 packets may be fragmented by the target route,
+		 * while IP6SKB_FRAG_SOURCE lets reassembly and ip6_fragment
+		 * preserve an existing translated Fragment Header.
+		 */
+		memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
+		skb->ignore_df = frag_source;
+		if (frag_source)
+			IP6CB(skb)->flags |= IP6SKB_FRAG_SOURCE;
+		return 0;
+	default:
+		DEBUG_NET_WARN_ON_ONCE(1);
+		return -EINVAL;
+	}
+}
+EXPORT_SYMBOL_GPL(ipxlat_translate);
 
 MODULE_DESCRIPTION("IPv6<>IPv4 stateless translation engine (SIIT)");
 MODULE_LICENSE("GPL");
-- 
2.55.0


  parent reply	other threads:[~2026-10-24  9:26 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-24  9:25 [RFC net-next v2 00/18] net: introduce ipxlat stateless IPv4/IPv6 translation Ralf Lici
2026-10-24  9:25 ` [RFC net-next v2 01/18] lwtunnel: track callback dispatch separately from return value Ralf Lici
2026-10-24  9:25 ` [RFC net-next v2 02/18] ipv4/ipv6: add LWT receive helpers Ralf Lici
2026-10-24  9:25 ` [RFC net-next v2 03/18] ipv6: allow output fragmentation to reuse a Fragment Header Ralf Lici
2026-10-24  9:25 ` [RFC net-next v2 04/18] netfilter: preserve IPv6 refragmentation state across reassembly Ralf Lici
2026-10-24  9:25 ` [RFC net-next v2 05/18] net: ipxlat: add engine skeleton and configuration model Ralf Lici
2026-10-24  9:25 ` [RFC net-next v2 06/18] net: ipxlat: add RFC 6052 and EAM address translation Ralf Lici
2026-10-24  9:25 ` [RFC net-next v2 07/18] net: ipxlat: add packet metadata and header helpers Ralf Lici
2026-10-24  9:25 ` [RFC net-next v2 08/18] net: ipxlat: add IPv4 packet validation Ralf Lici
2026-10-24  9:25 ` [RFC net-next v2 09/18] net: ipxlat: add IPv6 " Ralf Lici
2026-10-24  9:25 ` [RFC net-next v2 10/18] net: ipxlat: add checksum and offload helpers Ralf Lici
2026-10-24  9:25 ` [RFC net-next v2 11/18] net: ipxlat: add IPv4/IPv6 header and transport translation Ralf Lici
2026-10-24  9:25 ` Ralf Lici [this message]
2026-10-24  9:25 ` [RFC net-next v2 13/18] net: ipxlat: add translator-generated ICMP errors Ralf Lici
2026-10-24  9:25 ` [RFC net-next v2 14/18] net: ipxlat: add ICMP informational translation Ralf Lici
2026-10-24  9:25 ` [RFC net-next v2 15/18] net: ipxlat: add ICMP error and quoted-packet translation Ralf Lici
2026-10-24  9:25 ` [RFC net-next v2 16/18] net: ipxlat: add lightweight tunnel attachment Ralf Lici
2026-10-24  9:25 ` [RFC net-next v2 17/18] selftests: net: add ipxlat coverage Ralf Lici
2026-10-24  9:25 ` [RFC net-next v2 18/18] docs: networking: add ipxlat guide 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=20261024092532.172005-13-ralf@mandelbit.com \
    --to=ralf@mandelbit.com \
    --cc=antonio@mandelbit.com \
    --cc=davem@davemloft.net \
    --cc=dsahern@kernel.org \
    --cc=dxld@darkboxed.org \
    --cc=edumazet@kernel.org \
    --cc=horms@kernel.org \
    --cc=idosch@nvidia.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=toke@kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.