Skip to main content

CGNAT Configuration

Configure CGNAT VRF steering to hand off subscriber traffic to an external CGNAT appliance.

Built-in Deterministic CGNAT — Coming Soon

A future release will include built-in nftables-based deterministic CGNAT. The VRF steering configuration described here will remain supported.

Overview​

The cgnat section configures VRF-based traffic steering for subscribers on RFC 6598 (Shared Address Space) IPs. AthenaBNG creates a Linux VRF, marks matching subscriber traffic with nftables, and routes it via a dedicated handoff interface to your external CGNAT appliance for NAT translation.

We recommend NFware vCGNAT for the external appliance — deterministic NAT, DPDK acceleration, and full translation logging for lawful intercept compliance. Any CGNAT appliance that accepts routed traffic on a handoff interface will work.

Configuration Options​

enabled​

Enable or disable CGNAT (optional).

cgnat:
enabled: true

Type: Boolean
Required: No
Default: false
Valid values: true, false

CLI:

abng# set cgnat enabled true

vrf_name​

VRF name for CGNAT traffic (optional).

cgnat:
vrf_name: "cgnat"

Type: String
Required: No
Default: "cgnat"
Constraints: 1-15 characters, alphanumeric and underscores

Purpose: Linux VRF name for CGNAT routing table.

CLI:

abng# set cgnat vrf_name "cgnat"

vrf_table​

Routing table ID for CGNAT VRF (optional).

cgnat:
vrf_table: 200

Type: Integer
Required: No
Default: 200
Constraints: Valid routing table ID (1-252)

Purpose: Linux routing table ID for CGNAT routes.

CLI:

abng# set cgnat vrf_table 200

handoff_interface​

Interface for CGNAT traffic handoff (optional).

cgnat:
handoff_interface: "eth3"

Type: String (interface name)
Required: No
Default: None
Constraints: Valid interface name

Purpose: Dedicated interface to CGNAT router.

CLI:

abng# set cgnat handoff_interface "eth3"

handoff_gateway​

Gateway IP for CGNAT handoff (optional).

cgnat:
handoff_gateway: "10.99.0.1"

Type: IPv4 address
Required: No
Default: None
Constraints: Valid IPv4 address

Purpose: Next-hop IP for CGNAT traffic.

CLI:

abng# set cgnat handoff_gateway "10.99.0.1"

source_range​

CGNAT source IP range (optional).

cgnat:
source_range: "100.64.0.0/10"

Type: CIDR notation
Required: No
Default: "100.64.0.0/10"
Constraints: Valid IPv4 CIDR

Purpose: IP range for CGNAT pool (RFC 6598 Shared Address Space).

CLI:

abng# set cgnat source_range "100.64.0.0/10"

fwmark​

Firewall mark for CGNAT traffic (optional).

cgnat:
fwmark: "0x64"

Type: String (hex format)
Required: No
Default: "0x64"
Constraints: Valid hex value (0x0-0xffffffff)

Purpose: nftables fwmark for identifying CGNAT traffic.

CLI:

abng# set cgnat fwmark "0x64"

Example Configurations​

Minimal CGNAT Configuration​

cgnat:
enabled: true
handoff_interface: "eth3"
handoff_gateway: "10.99.0.1"

Uses defaults:

  • VRF name: "cgnat"
  • VRF table: 200
  • Source range: "100.64.0.0/10"
  • Fwmark: "0x64"

Full CGNAT Configuration​

cgnat:
enabled: true
vrf_name: "cgnat"
vrf_table: 200
handoff_interface: "eth3"
handoff_gateway: "10.99.0.1"
source_range: "100.64.0.0/10"
fwmark: "0x64"

With BGP Aggregate Announcements​

cgnat:
enabled: true
vrf_name: "cgnat"
vrf_table: 200
handoff_interface: "eth3"
handoff_gateway: "10.99.0.1"
source_range: "100.64.0.0/10"
fwmark: "0x64"
announce_aggregates:
- "203.0.113.0/24"

Configuration via CLI​

Enable CGNAT​

abng> configure
abng# set cgnat enabled true
abng# commit

Set Handoff Interface​

abng# set cgnat handoff_interface "eth3"
abng# set cgnat handoff_gateway "10.99.0.1"
abng# commit

Set VRF Parameters​

abng# set cgnat vrf_name "cgnat"
abng# set cgnat vrf_table 200
abng# commit

Verification​

View CGNAT Configuration​

abng> show configuration | match "^cgnat:"
cgnat:
enabled: true
vrf_name: cgnat
vrf_table: 200
handoff_interface: eth3
handoff_gateway: 10.99.0.1
source_range: 100.64.0.0/10
fwmark: 0x64

Check VRF Status​

ip vrf show
Name Table
cgnat 200

Check CGNAT Routes​

ip route show table 200
default via 10.99.0.1 dev eth3

Check nftables Rules​

sudo nft list table inet abng_cgnat
table inet abng_cgnat {
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
...
}
}

Check abngd Logs​

sudo journalctl -u abngd -f | grep -i cgnat

Integration with RADIUS​

CGNAT assignment can be controlled via RADIUS:

radius:
servers:
- host: "10.255.0.10"
secret: "your-secret"

RADIUS attributes:

  • Athena-CGNAT-Enable — Enable CGNAT for subscriber (true/false)
  • Athena-CGNAT-Address — Specific CGNAT IP (optional)

How VRF Steering Works​

Traffic Flow​

Packet Marking​

nftables marks packets with fwmark when the subscriber's IP falls within the configured source_range. The mark triggers policy routing into the CGNAT VRF.

VRF Routing​

Marked packets are routed via the CGNAT VRF:

  1. ip rule matches fwmark → lookup in CGNAT routing table
  2. Default route in VRF points to handoff_gateway via handoff_interface
  3. External CGNAT appliance (e.g. NFware vCGNAT) performs NAT translation
  4. Return traffic follows normal routing

RFC 6598 Shared Address Space​

The default CGNAT source range (100.64.0.0/10) is defined in RFC 6598:

  • Range: 100.64.0.0 to 100.127.255.255
  • Purpose: Carrier-Grade NAT (CGN) address space
  • Size: 4,194,304 addresses
  • Usage: RADIUS assigns addresses from this range to subscribers requiring CGNAT

Validation Rules​

FieldValidation
enabledBoolean
vrf_name1-15 characters, alphanumeric and underscores
vrf_tableInteger 1-252
handoff_interfaceValid interface name
handoff_gatewayValid IPv4 address
source_rangeValid CIDR notation
fwmarkValid hex value

Best Practices​

  1. Dedicated Interface — Use a dedicated interface for CGNAT handoff
  2. VRF Isolation — Use separate VRF for CGNAT traffic
  3. Fwmark — Use unique fwmark to avoid conflicts
  4. RADIUS Integration — Use RADIUS to control CGNAT per-subscriber
  5. Monitoring — Monitor CGNAT session count and translation stats
  6. Testing — Test with traceroute to verify CGNAT routing
  7. Documentation — Document CGNAT pool allocation and management

Troubleshooting​

CGNAT Not Translating​

  1. Check CGNAT is enabled: show configuration | match cgnat
  2. Check VRF exists: ip vrf show
  3. Check nftables rules: sudo nft list table inet abng_cgnat
  4. Check RADIUS returns CGNAT attributes: radtest testuser testpass <radius-ip> 1812 <secret>
  5. Check abngd logs: journalctl -u abngd -f

CGNAT Traffic Not Reaching Router​

  1. Check handoff interface is up: ip link show eth3
  2. Check route exists: ip route show table 200
  3. Check gateway is reachable: ping 10.99.0.1
  4. Check nftables rules: sudo nft list table inet abng_cgnat

Return Traffic Not Working​

  1. Check CGNAT router is translating return traffic
  2. Check reverse route exists: ip route show table 200
  3. Check firewall allows return traffic
  4. Check CGNAT router logs

Next Steps​