bngxdpd 3.6.0 · Stateless IPv6 Transition · MAP-E / MAP-T Border Relay
IPv6 Transition · CGNAT Alternative · bngxdpd 3.6.0

A stateless Border Relay: no conntrack, no session table for a flood to exhaust

Stateful CGNAT tracks every open connection in a session table sized for the worst case — and a connection flood or DDoS can fill that table. BNGSOFT's MAP-E / MAP-T Border Relay takes a different path: a subscriber's public IPv4 address and port-set are computed algorithmically from their IPv6 prefix, never stored or looked up per flow. There is no per-flow state to exhaust, because there is no per-flow state. It runs in the same native XDP fast path as bngxdpd's existing CGNAT, selected per deployment via a single config switch, alongside the unchanged stateful default.
Stateless
by design
public IPv4 + port-set computed from the subscriber's IPv6 prefix — never stored per flow
No ceiling
to exhaust
a connection flood or DDoS cannot fill a session table that does not exist
Native XDP
same fast path
the existing bngxdpd eBPF data plane, in the NIC driver — no new appliance
Opt-in
cgnat.engine=mapt
coexists with the unchanged stateful default; select per deployment
A flood cannot exhaust a table that was never allocated. Remove the state, and you remove the failure mode it enables.

The classic cost: a session table sized for the worst case

Stateful CGNAT keeps a connection-tracking record for every active session — private 5-tuple, allocated public IP:port, timeout — in a table that must be sized for the busiest moment the box will ever see. That table is finite. Under a connection flood or a DDoS attack, an attacker's goal is often simply to fill it: once the ceiling is reached, new legitimate sessions have nowhere to go.

Stateful CGNAT — the failure mode

The table is the attack surface

  • Every open connection is a record that must be tracked, refreshed and eventually reaped.
  • The table is sized for a worst-case session ceiling — finite by construction.
  • A connection flood or DDoS aims at exactly that ceiling: fill the table, and legitimate new sessions are the ones that get turned away.
  • Defending it means rate-limiting, aggressive reaping and DDoS mitigation layered on top of the state.
Stateless MAP-E / MAP-T — the answer

There is no table to fill

  • No per-flow conntrack record is created, tracked or reaped at all.
  • A subscriber's public address and port-set are a function of their IPv6 prefix — computed on the fly, every time.
  • A connection flood still has to be handled as traffic, but it cannot exhaust state that was never allocated.
  • This does not replace BNGSOFT's DDoS protection — it removes an entire class of thing DDoS could otherwise target.

Stateless by construction: the mapping is computed, not stored

MAP-E and MAP-T share the same address-mapping foundation defined in RFC 7597. Each subscriber's IPv6 prefix is combined with a small set of operator-provisioned mapping-rule parameters — a Basic Mapping Rule (BMR) — to derive, algorithmically, the subscriber's public IPv4 address and a restricted port-set, identified by a PSID (Port Set Identifier) carried in the bits of the address itself. Nothing about this mapping is looked up in a table: it is arithmetic, run the same way on every packet.

Subscriber IPv6 prefix 2001:db8:1:200::/56 Basic Mapping Rule (BMR) RFC 7597 — computed, not looked up Public IPv4 address shared across subscribers Port-set (PSID) restricted range this CE owns
The subscriber's IPv6 prefix goes into the mapping function; the public IPv4 address and the port-set this subscriber's CE is allowed to use come out. Run the arithmetic in reverse — from a public IP:port — and the same function returns the subscriber. No table sits in the middle.

Stateful CGNAT — packet path

// session table, fixed at load, held always session_table[ MAX_SESSIONS ] // finite ceiling on packet: key := hash(5-tuple) entry := session_table.lookup(key) if not entry: if table full: DROP // the failure mode entry := allocate_and_track(key)

MAP-E / MAP-T — packet path

// no table declared — nothing to fill on packet: prefix := subscriber_ipv6_prefix(pkt) public_ip, port_set := BMR(prefix) // computed // translate/encapsulate using the result // — always resolves, no lookup, no ceiling

MAP-E or MAP-T — encapsulation or translation, your choice

Both modes share the same stateless RFC 7597 address mapping; they differ in what happens to the packet on the wire. The operator selects per deployment.

DimensionMAP-E — RFC 7597 (encapsulation)MAP-T — RFC 7599 / RFC 7915 SIIT (translation)
Mechanism The IPv4 packet is wrapped inside an IPv6 tunnel between CE and Border Relay — a full IPv4-in-IPv6 encapsulation. The IPv4 header is translated to/from IPv6 using the SIIT algorithm (RFC 7915) and the same algorithmic address — no tunnel.
Packet on the wire Outer IPv6 header + the original IPv4 packet, untouched, inside it. A single translated header per hop — native IPv6 on the v6 side, native IPv4 on the v4 side.
Where it fits best When the original IPv4 packet needs to survive the trip completely unmodified, or CPE/ecosystem support is built around the encapsulation model. When the network is IPv6-only end to end and you want to avoid tunnel/encapsulation overhead — a natural fit alongside SIIT/NAT64-style infrastructure.
Stateless mapping Yes — RFC 7597 BMR/PSID Yes — same BMR/PSID, RFC 7599
Data plane Native XDP/eBPF, same fast path as CGNAT Native XDP/eBPF, same fast path as CGNAT

Both modes are available in bngxdpd 3.6.0; the operator selects the engine and mode per deployment:

// bngxdpd config — select the stateless Border Relay engine and mode "cgnat": { "engine": "mapt", // default remains "maps" (stateful) — unchanged "mapt": { "mode": "t" // "e" for MAP-E, "t" for MAP-T // + standard RFC 7597 mapping-rule parameters // (BR prefix, rule IPv4 prefix, EA-bits length / PSID) } }
PSID anti-spoofing on the upload path. Because a subscriber's port-set is derived from their own IPv6 prefix, the Border Relay can check that upstream traffic's source port actually falls within the PSID-derived range that CE is entitled to. A CE can only source the ports it algorithmically owns — traffic claiming a port outside that set is not a valid mapping for that subscriber, a spoofing check that falls out of the design rather than needing a separate table.

Compliance & lawful intercept: unchanged, by design

Removing the session table does not remove the traceability requirement — and it was a hard requirement for this design. Two things hold exactly as they do today:

DETERMINISTIC IDENTIFICATION

The subscriber is computed, not searched for

  • Given a timestamp, a public IP and a port, the subscriber is recovered by running the same mapping function in reverse — not by searching through log archives.
  • Because the forward mapping is deterministic, the reverse mapping is too: there is nothing ambiguous or time-limited about the answer.
  • This is the same property that makes the forward path stateless — it identifies subscribers instead of needing per-flow state to do it.
FLOW LOGGING — AT PARITY

Nothing about the LI workflow changes

  • Full per-session flow logging — IPFIX and syslog — is retained at parity with stateful CGNAT.
  • The government / lawful-intercept request workflow is exactly as it is today.
  • IPv6 traffic logging continues exactly as today, unaffected by the transition mechanism underneath.
Why this mattered before anything else got built. A stateless data plane could easily have been stateless about compliance too — that was never acceptable. MAP-E/MAP-T keeps the full flow-logging pipeline (IPFIX via bngipfixd, syslog into your SIEM) running exactly as it does for stateful CGNAT, and adds a deterministic, computed identification path on top — so the operator's regulatory obligations do not change with the engine underneath them.

Where it fits: native XDP, opt-in, coexisting

MAP-E/MAP-T is a third engine option inside bngxdpd's existing engine-gated CGNAT architecture — it does not replace anything, and it does not require new hardware.

maps (default, unchanged)

Stateful CGNAT

  • Twin session tables, per-flow tracking.
  • Production default — untouched by this release.
arena (next-gen conntrack)

Runtime-allocated stateful

  • One unified record, memory that tracks real sessions.
  • Still stateful — in active validation.
mapt (this release)

Stateless Border Relay

  • MAP-E or MAP-T, no conntrack at all.
  • Opt-in via cgnat.engine=mapt; new in 3.6.0.

Same native XDP fast path

Runs in the same eBPF data plane as existing bngxdpd CGNAT, in the NIC driver — native XDP, no new appliance, no separate box to rack.

Opt-in, one switch

cgnat.engine=mapt selects the stateless Border Relay explicitly. Leave it unset and nothing changes — the stateful maps engine remains the default.

Coexists, doesn't replace

Existing deployments on maps (or validating arena) are entirely untouched by this release. MAP-E/MAP-T is an additional path for operators actively working IPv6 transition.

Less state to carry, less to log. Deterministic port-sets replace per-flow port allocation entirely — there is no per-connection state to track in the first place, which shrinks both the runtime state footprint and the logging burden relative to stateful CGNAT, without giving up the flow-level compliance record.

The honest state of play

MAP-E/MAP-T is new in bngxdpd 3.6.0, selected by an explicit engine switch. The stateful maps engine remains the production default and is unchanged. Live, at-scale validation of the stateless Border Relay is in progress — we are not claiming a production deployment milestone here, and this brief makes no throughput, capacity, or benchmark claims.

What is real today: the RFC 7597 / RFC 7599 stateless address-and-port-set mapping, both MAP-E and MAP-T modes, the native-XDP data plane, PSID-based upload-path validation, and full flow-logging parity for compliance. What is in the lab: live-traffic soak validation ahead of broader rollout.

Evaluating IPv6 transition or hitting a CGNAT state-table ceiling? We will walk through the mapping-rule design, the compliance model, and the validation plan on a node running real traffic.

Sources & honest framing: This is a customer-facing engineering brief — not a benchmark report. No throughput, subscriber-count, or benchmark figures are claimed, and this release is not described as deployed in production: MAP-E/MAP-T is new in bngxdpd 3.6.0 and is undergoing live validation. MAP-E is defined by RFC 7597 (Mapping of Address and Port with Encapsulation); MAP-T is defined by RFC 7599, sharing the same RFC 7597 address/port-mapping format but using stateless IP/ICMP translation (SIIT, RFC 7915) instead of encapsulation. In both modes, a subscriber's public IPv4 address and restricted port-set (identified by a PSID) are derived algorithmically from their IPv6 prefix via a Basic Mapping Rule — this mapping is computed on each packet and is never stored as a per-flow session record, which is the basis for the "no session-table ceiling" claim: there is no per-flow conntrack table for a connection flood or DDoS to exhaust. This does not replace or diminish BNGSOFT's separate DDoS-protection features. The data plane runs as a Border Relay function inside bngxdpd's existing native XDP/eBPF fast path — the same forwarding path used by bngxdpd's stateful CGNAT — requiring no additional appliance. The engine is selected explicitly via the cgnat.engine=mapt configuration switch, with mode (MAP-E or MAP-T) selected via cgnat.mapt.mode; the stateful maps engine remains the unchanged, byte-identical production default when this switch is not set, and this release coexists with (does not replace) the map-based engine and the separately-validating BPF-arena conntrack engine. The mapping-rule JSON shown is illustrative of the two documented configuration keys (cgnat.engine, cgnat.mapt.mode); the additional RFC 7597 mapping-rule parameters (BR prefix, rule IPv4 prefix, EA-bits length/PSID sizing) are standard to the protocol and are referenced generically here, not itemized as literal product schema. Compliance and lawful-intercept behavior is unchanged by this engine: full per-session flow logging (IPFIX via bngipfixd, and syslog) is retained at parity with stateful CGNAT, and the deterministic mapping additionally allows a subscriber to be identified computationally from a {timestamp, public IP, port} tuple, without a log-archive search, using the same reverse mapping function described above. The address-mapping and packet-path diagrams and code comparisons in this document are conceptual illustrations of the architecture, not measured results or literal wire/log captures. Not legal advice: exact regulatory obligations vary by jurisdiction; BNGSOFT provides the traceability mechanism and standard export, and mapping that to a specific legal regime is the operator's responsibility in consultation with counsel. Related briefs — CGNAT Arena Engine, Compliance / CGNAT Logging, Full CGNAT — are available alongside this guide.