Guides

NAT

Source NAT, port forwarding, and NAT exemptions (nat44_ed).

SiHA runs VPP’s nat44_ed engine — an endpoint-dependent NAT44 implementation that handles dynamic source NAT, static (1:1 / port-forward) mappings, and explicit exemptions from translation, all driven by declarative COSI resources.

Four resource types cover the full NAT lifecycle:

ResourcePurpose
NATInterfaceModes.nat.sihaMark an interface as INSIDE, OUTSIDE, or both
NATPools.nat.sihaAddress range(s) from which dynamic SNAT picks translated IPs
NATStaticMappings.nat.siha1:1 address or port-forward (DNAT / static SNAT)
NATIdentityMappings.nat.sihaExempt a host (or port/protocol) from translation

How it works

nat44_ed tracks sessions bidirectionally. For a session to form, at least one interface must be marked INSIDE (the client-facing side) and at least one OUTSIDE (the internet-facing side). Traffic from an INSIDE interface is dynamically SNAT’d to an address from the pool unless overridden by a static or identity mapping.

Interface modes

# Mark the LAN-facing interface as INSIDE.
type: NATInterfaceModes.nat.siha
metadata: { namespace: nat, id: int }
spec:
  interface: int        # COSI id of an Interfaces.link.siha resource
  mode: INSIDE
---
# Mark the WAN-facing interface as OUTSIDE.
type: NATInterfaceModes.nat.siha
metadata: { namespace: nat, id: ext }
spec:
  interface: ext
  mode: OUTSIDE

Valid mode values: INSIDE, OUTSIDE, INSIDE_AND_OUTSIDE.

Address pool (dynamic SNAT)

type: NATPools.nat.siha
metadata: { namespace: nat, id: snat-pool }
spec:
  ranges:
    - { first: 203.0.113.100, last: 203.0.113.110 }
  # vrf: tenant-a   # omit for the default VRF (table 0)

ranges is a list of [first, last] inclusive IPv4 ranges. A pool with zero ranges is valid but does nothing — useful as a placeholder.

Static mapping (1:1 / port forward)

Static mappings are bidirectional: inbound traffic to externalAddress:externalPort is translated to localAddress:localPort, and outbound traffic from the local address is translated to the external address.

Port forward (DNAT) — redirect TCP 443 to an internal host:

type: NATStaticMappings.nat.siha
metadata: { namespace: nat, id: web-dnat }
spec:
  externalAddress: 203.0.113.1
  externalPort: 443
  localAddress: 10.0.1.80
  localPort: 443
  protocol: tcp        # name (tcp, udp, icmp, …) or a raw number
  # vrf: ""            # omit for the default VRF

protocol, externalPort, and localPort must all be set together, or all omitted (which expresses a 1:1 address-only mapping for any protocol). protocol takes a name (tcp, udp, icmp, icmp6, sctp) or a number; sihactl reads and prints the name.

NAT exemption (identity mapping)

Without an identity mapping, every flow from an INSIDE interface is SNAT’d. An identity mapping exempts a specific host (or per-protocol port) from translation, so it appears on the network with its own address:

# Exempt the appliance's own loopback from SNAT (address-only).
type: NATIdentityMappings.nat.siha
metadata: { namespace: nat, id: lo-exempt }
spec:
  address: 10.0.1.1
  # port: 53
  # protocol: udp     # if set, both port and protocol must be set
  # vrf: ""

port and protocol are jointly optional: both zero means all protocols and ports for that address are exempted. When either is set, both must be.

Operating

S="sihactl --sihaconfig ~/.siha/config --addr <node-ip>:6443"

$S get natinterfacemode          # list interface modes + status
$S get natpool                   # list address pools
$S get natstaticmapping          # list static mappings
$S get natidentitymapping        # list identity (exemption) mappings

$S nat sessions                  # dump active NAT44 translation sessions

nat sessions is a live VPP-state dump — it is not backed by a COSI resource. It shows inside, outside, and external-host address/port tuples, protocol, VRF table, cumulative bytes/packets, and whether the session has timed out.

Each resource type has a paired status (e.g. NATPoolStatus) that reports the last error and the programmed ranges; sihactl get natpool <id> -o yaml shows both spec and status in one output.

Interaction with the load balancer

NATLBMapping (the SiHA load balancer) runs on the same nat44_ed engine as these NAT rules: one session table, coexisting on the same interfaces without conflict — just don’t reuse a NAT pool address as a LB VIP.