mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [RFC net-next v2 00/18] net: introduce ipxlat stateless IPv4/IPv6 translation
@ 2026-10-24  9:25 Ralf Lici
  2026-10-24  9:25 ` [RFC net-next v2 01/18] lwtunnel: track callback dispatch separately from return value Ralf Lici
                   ` (17 more replies)
  0 siblings, 18 replies; 19+ messages in thread
From: Ralf Lici @ 2026-10-24  9:25 UTC (permalink / raw)
  To: netdev
  Cc: David Ahern, Ido Schimmel, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman,
	Toke Høiland-Jørgensen, Beniamino Galvani,
	Xavier Hsinyuan, Daniel Gröber, Antonio Quartulli,
	Pablo Neira Ayuso, Florian Westphal, Phil Sutter,
	netfilter-devel, coreteam, linux-kernel

Hi all,

apologies for the long gap since RFC v1; the attachment redesign and the
related fragmentation work took longer than expected.

This RFC introduces ipxlat, an in-kernel engine for stateless IPv4/IPv6
and ICMP translation, together with a lightweight-tunnel attachment.

ipxlat implements the SIIT algorithm from RFC 7915, RFC 6052 address
embedding, optional RFC 7757 Explicit Address Mapping, transport
checksum and GSO metadata, and ICMP translation including quoted packets
and RFC 4884 extensions. It is intended as a common building block for
CLAT, stateful NAT64, 464XLAT, and SIIT border translators.

NetworkManager currently provides CLAT with BPF [1], and
systemd-networkd is developing a similar implementation [2]. Those
implementations cannot cover some paths which need facilities outside
the BPF program, including fragmentation, fragmented ICMP, and complete
checksum generation for zero-checksum UDPv4. A reusable native
translator lets network managers share those mechanisms rather than each
maintaining another partial implementation.

This RFC has 18 patches. The first four are networking-core
prerequisites for LWT continuation and IPv6 refragmentation. Keeping the
remaining 14 changes separate makes the engine, LWT attachment,
selftests, and documentation substantially easier to review. NIPA’s
series_format will complain that the series is too long, but the split
can be adjusted for a non-RFC posting once the design has settled.

See Documentation/networking/ipxlat.rst for the full configuration and
operational model.

The latest code can also be found at:
https://codeberg.org/IPv6-Monostack/ipxlat-net-next


== Architecture ==

RFC v1 exposed ipxlat as a virtual netdevice which translated packets in
ndo_start_xmit and injected them back into the receive path. Review
identified that this required artificial device, MTU, routing, and
statistics semantics and made the packet appear to have arrived from a
device after translation.

v2 instead separates a reusable engine under net/ipxlat from its (first)
attachment. An IPv4 or IPv6 route carrying encap ipxlat selects the
packet and supplies immutable translation configuration. The selecting
route terminates in translation; after the family switch, the packet
gets a fresh route in the translated family. There is no translator
device or ipxlat-specific netlink family.

The engine performs validation and translation but does not decide which
traffic should use it. Routing rules and filters remain responsible for
deployment policy such as CLAT source selection and downstream source
validation. Keeping the engine independent also leaves room for later
netfilter or BPF kfunc attachments without duplicating the translator.


== Address configuration ==

Each attachment has one required RFC 6052 prefix and an optional RFC
7757 Explicit Address Mapping. Each source and destination is considered
independently: an EAM match takes precedence, while an address outside
the EAM uses RFC 6052 conversion.

This represents both CLAT addressing models requested during v1 review.
A single-host CLAT maps one dedicated IPv4 address to one IPv6 address.
A delegated-prefix CLAT maps the downstream IPv4 prefix into a prefix
delegated to the CLAT, while remote IPv4 destinations continue to use
the far-side NAT64 prefix. This v2 accepts at most one EAM per
attachment and does not implement RFC 7757 hairpinning.

Configuration belongs to each selecting route rather than to a shared
ipxlat object. A bidirectional setup therefore repeats the configuration
on its original and translated family selecting routes. Userspace must
update both routes whenever a configured address or prefix changes, for
example after DHCPv6-PD assigns a new prefix.

The dev associated with an ipxlat route belongs only to the
original family selecting route; it is not a translator interface and
does not select the translated packet's egress device. The fresh
translated family route lookup does that.


== Family switch and policy traversal ==

The original family route lookup ends at the LWT callback. The callback
discards route, conntrack, security, socket, and other metadata which no
longer describes the translated packet.

For received traffic, the translated packet enters the translated
family's PRE_ROUTING hook and receives a fresh route lookup. For locally
originated traffic, it enters translated family LOCAL_OUT with no
socket. The normal translated family path then owns:
- forwarding,
- TTL or Hop Limit,
- PMTU,
- XFRM,
- conntrack, and
- NAT.

This allows a stateful NAT64 PLAT to be built from stateless ipxlat plus
ordinary IPv4 conntrack and masquerading. No conntrack object crosses
the family switch.

Translated output is socketless. It uses the normal kernel-originated
UID and global XFRM policy; socket, cgroup, and per socket XFRM identity
cannot cross the family switch.

If preparation determines that a packet is valid but unsupported, the
LWT invokes the route's original input or output callback and leaves the
packet in its original family. This is needed, for example, so native
IPv6 Neighbor Discovery still works for a local address selected by an
ipxlat route. Malformed packets and failures after translation begins
are dropped.

This continuation is the central semantic choice in v2. Does PRE_ROUTING
for received translated traffic and LOCAL_OUT for locally generated
translated traffic provide the right policy visibility for a
cross-family LWT action? And does the harness discard and retain the
right skb metadata across the family switch?


== Fragmentation ==

v1 fragmented oversized DF-clear IPv4 packets before translation, using
a synthetic route to supply an MTU. v2 translates first and lets IPv6
output use the real translated route and PMTU.

IPv4 packets which are already fragments carry an IPv6 Fragment Header
after translation. This series extends IPv6 output so it can fragment
that representation again while preserving the translated
identification, base offset, and More Fragments state. IPv6 conntrack
reassembly preserves the indication needed for the later output path to
do the same. An MTU metric on a translated family route can be used as
an administrative ceiling where Packet Too Big feedback is unreliable.

If an earlier original-family component has already reassembled a
datagram, ipxlat cannot recover its previous fragment boundaries or
identification. Fragmented ICMP and zero-checksum UDPv4 must likewise be
reassembled before translation because their translated checksums need
the complete datagram.


== Testing ==

The selftests use an iproute2-configured namespace topology and cover:
- local and forwarded translation,
- native fallback,
- zero-checksum UDPv4,
- translated family conntrack and masquerading,
- route-PMTU fragmentation,
- conntrack reassembly followed by refragmentation,
- PMTU feedback, and
- ICMP errors.

Along with this series, an iproute2 ipxlat-enabled tree is provided [3].

[1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/1.57.2-dev/src/core/bpf/clat.bpf.c
[2] https://github.com/systemd/systemd/pull/41412
[3] https://codeberg.org/IPv6-Monostack/iproute2/src/branch/ipxlat-lwt


== Points for discussion ==

- Is the translated-family continuation described above the right
  contract for an LWT family switch?

- Is an LWT attachment with inline immutable route configuration the
  right first harness for the reusable engine?

- Is reusing an existing IPv6 Fragment Header in the output
  fragmentation path a suitable general mechanism for translated IPv4
  fragments?


== Acknowledgements ==

The ipxlat translation engine is derived from Jool so it can benefit
from the project's accumulated implementation experience and
golden-packet tests. Thanks to Jool's principal author, Alberto Leiva
Popper, for maintaining that work and for writing the original joolif
prototype from which ipxlat started.

Thanks to Toke Høiland-Jørgensen, Beniamino Galvani, Xavier Hsinyuan,
and Jonathan Corbet for their RFC v1 review and deployment input.

Thanks to NLnet's NGI0 Core Fund for supporting ipxlat development.


Thanks for your review,

Ralf Lici
Mandelbit SRL

---

Changes since RFC v1 https://lore.kernel.org/netdev/20260319151230.655687-1-ralf@mandelbit.com/

- Replaced the virtual netdevice and generic-netlink control plane with
  a reusable translation engine under net/ipxlat and a route-selected
  LWT attachment. Deployment policy remains outside the engine. (Toke)

- Added an optional RFC 7757 EAM before RFC 6052 conversion, covering
  both single-host and delegated-prefix CLAT addressing. (Beniamino)

- Defined received and local traffic continuations into the translated
  family, including fresh routing, conntrack, NAT, and XFRM processing.
  Added native LWT fallback for packets the engine does not support.

- Removed the lowest-ipv6-mtu parameter and IPv4 pre-fragmentation. The
  translated IPv6 route now owns PMTU and fragmentation, including
  refragmentation which preserves an existing Fragment Header across
  conntrack reassembly.

- Moved TTL and Hop Limit handling to the translated family forwarding
  path, so translation itself does not consume a hop.

- Replaced the v1 netdevice tests and documentation with LWT coverage
  and deployment examples.


Ralf Lici (18):
  lwtunnel: track callback dispatch separately from return value
  ipv4/ipv6: add LWT receive helpers
  ipv6: allow output fragmentation to reuse a Fragment Header
  netfilter: preserve IPv6 refragmentation state across reassembly
  net: ipxlat: add engine skeleton and configuration model
  net: ipxlat: add RFC 6052 and EAM address translation
  net: ipxlat: add packet metadata and header helpers
  net: ipxlat: add IPv4 packet validation
  net: ipxlat: add IPv6 packet validation
  net: ipxlat: add checksum and offload helpers
  net: ipxlat: add IPv4/IPv6 header and transport translation
  net: ipxlat: add translation preparation and dispatch
  net: ipxlat: add translator-generated ICMP errors
  net: ipxlat: add ICMP informational translation
  net: ipxlat: add ICMP error and quoted-packet translation
  net: ipxlat: add lightweight tunnel attachment
  selftests: net: add ipxlat coverage
  docs: networking: add ipxlat guide

 Documentation/networking/index.rst           |   1 +
 Documentation/networking/ipxlat.rst          | 333 ++++++++++
 include/linux/ipv6.h                         |   2 +
 include/net/ip.h                             |   1 +
 include/net/ipv6.h                           |   2 +
 include/net/ipv6_frag.h                      |   2 +
 include/net/ipxlat.h                         | 113 ++++
 include/uapi/linux/ipxlat.h                  |  56 ++
 include/uapi/linux/lwtunnel.h                |   1 +
 net/Kconfig                                  |   1 +
 net/Makefile                                 |   1 +
 net/core/lwtunnel.c                          |  15 +-
 net/ipv4/ip_input.c                          |  10 +
 net/ipv6/ip6_input.c                         |  11 +
 net/ipv6/ip6_output.c                        |  53 +-
 net/ipv6/netfilter/nf_conntrack_reasm.c      |  11 +-
 net/ipxlat/Kconfig                           |  27 +
 net/ipxlat/Makefile                          |  19 +
 net/ipxlat/address.c                         | 218 +++++++
 net/ipxlat/address.h                         |  57 ++
 net/ipxlat/config.c                          |  82 +++
 net/ipxlat/core.c                            | 156 +++++
 net/ipxlat/icmp.h                            |  70 ++
 net/ipxlat/icmp_46.c                         | 588 +++++++++++++++++
 net/ipxlat/icmp_64.c                         | 615 ++++++++++++++++++
 net/ipxlat/lwt.c                             | 643 +++++++++++++++++++
 net/ipxlat/packet.h                          | 243 +++++++
 net/ipxlat/packet4.c                         | 410 ++++++++++++
 net/ipxlat/packet6.c                         | 468 ++++++++++++++
 net/ipxlat/translate_46.c                    | 217 +++++++
 net/ipxlat/translate_46.h                    |  77 +++
 net/ipxlat/translate_64.c                    | 226 +++++++
 net/ipxlat/translate_64.h                    |  96 +++
 net/ipxlat/transport.c                       | 179 ++++++
 net/ipxlat/transport.h                       | 127 ++++
 tools/testing/selftests/Makefile             |   1 +
 tools/testing/selftests/net/ipxlat/Makefile  |   5 +
 tools/testing/selftests/net/ipxlat/config    |  13 +
 tools/testing/selftests/net/ipxlat/ipxlat.sh | 554 ++++++++++++++++
 39 files changed, 5694 insertions(+), 10 deletions(-)
 create mode 100644 Documentation/networking/ipxlat.rst
 create mode 100644 include/net/ipxlat.h
 create mode 100644 include/uapi/linux/ipxlat.h
 create mode 100644 net/ipxlat/Kconfig
 create mode 100644 net/ipxlat/Makefile
 create mode 100644 net/ipxlat/address.c
 create mode 100644 net/ipxlat/address.h
 create mode 100644 net/ipxlat/config.c
 create mode 100644 net/ipxlat/core.c
 create mode 100644 net/ipxlat/icmp.h
 create mode 100644 net/ipxlat/icmp_46.c
 create mode 100644 net/ipxlat/icmp_64.c
 create mode 100644 net/ipxlat/lwt.c
 create mode 100644 net/ipxlat/packet.h
 create mode 100644 net/ipxlat/packet4.c
 create mode 100644 net/ipxlat/packet6.c
 create mode 100644 net/ipxlat/translate_46.c
 create mode 100644 net/ipxlat/translate_46.h
 create mode 100644 net/ipxlat/translate_64.c
 create mode 100644 net/ipxlat/translate_64.h
 create mode 100644 net/ipxlat/transport.c
 create mode 100644 net/ipxlat/transport.h
 create mode 100644 tools/testing/selftests/net/ipxlat/Makefile
 create mode 100644 tools/testing/selftests/net/ipxlat/config
 create mode 100755 tools/testing/selftests/net/ipxlat/ipxlat.sh

-- 
2.55.0


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

end of thread, other threads:[~2026-10-24  9:26 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [RFC net-next v2 12/18] net: ipxlat: add translation preparation and dispatch Ralf Lici
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

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

all inboxes | Powered by JetHome®