Page MenuHomeVyOS Platform

VPP NAT: All traffic get NATed if out interface is set with output-feature
Open, NormalPublicBUG

Description

Topology

image.png (262×662 px, 22 KB)

Configuration commands:

set interfaces ethernet eth0 address 192.168.122.210/24
set interfaces ethernet eth1 address 100.64.0.1/24
set interfaces ethernet eth2 address '200.64.0.1/24'
set protocols static route 0.0.0.0/0 next-hop 192.168.122.1

set vpp settings lcp ignore-kernel-routes
set vpp settings interface eth0 driver 'dpdk'
set vpp settings interface eth1 driver 'dpdk'
set vpp settings interface eth2 driver 'dpdk'
set vpp settings unix poll-sleep-usec '122'
vyos@vyos# cat /run/vpp/vpp.conf | grep plugin
plugins {
    path /usr/lib/x86_64-linux-gnu/vpp_plugins/
    plugin default { disable }
    plugin af_xdp_plugin.so { enable }
    plugin avf_plugin.so { enable }
    plugin dpdk_plugin.so { enable }
    plugin vmxnet3_plugin.so { enable }
    plugin lacp_plugin.so { enable }
    plugin linux_cp_plugin.so { enable }
    plugin linux_nl_plugin.so { enable }
    plugin pppoe_plugin.so { enable }
    # plugin cnat_plugin.so { enable }
    plugin nat_plugin.so { enable }
    plugin nat44_ei_plugin.so { enable }
    # plugin nat44_ei_plugin.so { enable }
    # plugin nat64_plugin.so { enable }
    # plugin nat66_plugin.so { enable }
    # plugin pnat_plugin.so { enable }
    plugin geneve_plugin.so { enable }
    plugin gre_plugin.so { enable }
    plugin vxlan_plugin.so { enable }
    # plugin ikev2_plugin.so { enable }
    # plugin dns_plugin.so { enable } # Probably required for FQDN peers
    # plugin wireguard_plugin.so { enable }

Additional VPP commands:

vyos@vyos:~$ sudo vppctl
    _______    _        _   _____  ___
 __/ __/ _ \  (_)__    | | / / _ \/ _ \
 _/ _// // / / / _ \   | |/ / ___/ ___/
 /_/ /____(_)_/\___/   |___/_/  /_/

vpp# nat44 plugin enable
vpp# nat44 forwarding enable
vpp# set interface nat44 out eth0 output-feature
vpp# set interface nat44 in eth1
vpp# nat44 add address 192.168.122.55 192.168.122.56
vpp# show nat44 interfaces
NAT44 interfaces:
 eth1 in
 eth0 output-feature in out
vpp# show nat44 sessions
NAT44 ED sessions:
-------- thread 0 vpp_main: 2 sessions --------
    i2o 100.64.0.10 proto ICMP port 31987 fib 0
    o2i 192.168.122.56 proto ICMP port 31987 fib 0
       external host 1.1.1.1:31987
       i2o flow: match: saddr 100.64.0.10 sport 31987 daddr 1.1.1.1 dport 31987 proto ICMP fib_idx 0 rewrite: saddr 192.168.122.56 daddr 1.1.1.1 icmp-id 31987 txfib 0
       o2i flow: match: saddr 1.1.1.1 sport 31987 daddr 192.168.122.56 dport 31987 proto ICMP fib_idx 0 rewrite: saddr 1.1.1.1 daddr 100.64.0.10 icmp-id 31987 txfib 0
       index 0
       last heard 282.35
       timeout in 59.23
       total pkts 104, total bytes 8750
       dynamic translation

    i2o 200.64.0.10 proto ICMP port 44080 fib 0
    o2i 192.168.122.56 proto ICMP port 44080 fib 0
       external host 8.8.8.8:44080
       i2o flow: match: saddr 200.64.0.10 sport 44080 daddr 8.8.8.8 dport 44080 proto ICMP fib_idx 0 rewrite: saddr 192.168.122.56 daddr 8.8.8.8 icmp-id 44080 txfib 0
       o2i flow: match: saddr 8.8.8.8 sport 44080 daddr 192.168.122.56 dport 44080 proto ICMP fib_idx 0 rewrite: saddr 8.8.8.8 daddr 200.64.0.10 icmp-id 44080 txfib 0
       index 1
       last heard 282.69
       timeout in 59.57
       total pkts 104, total bytes 9464
       dynamic translation

We cannot nat specific local interface traffic even if in interface is set

One more issue:

in and out interface is set without output-feature:

Vpp commands

vpp# set interface nat44 in eth1
vpp# set interface nat44 out eth0
vpp# show nat44 interfaces
NAT44 interfaces:
 eth1 in
 eth0 out

We cannot ping from Client-2 (as expected)
But when stop pings from Client-1 and then start pinging again it doesnt work

64 bytes from 1.1.1.1: icmp_seq=4125 ttl=126 time=7.26 ms
64 bytes from 1.1.1.1: icmp_seq=4126 ttl=126 time=6.65 ms
64 bytes from 1.1.1.1: icmp_seq=4127 ttl=126 time=7.38 ms
64 bytes from 1.1.1.1: icmp_seq=4128 ttl=126 time=7.31 ms
64 bytes from 1.1.1.1: icmp_seq=4129 ttl=126 time=7.19 ms
64 bytes from 1.1.1.1: icmp_seq=4130 ttl=126 time=7.39 ms
^C
--- 1.1.1.1 ping statistics ---
4130 packets transmitted, 2589 received, 37.3123% packet loss, time 4171678ms
rtt min/avg/max/mdev = 5.113/9.117/125.106/6.373 ms
vyos@vyos:~$ ping 1.1.1.1
PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.

VPP API:

from vyos.vpp import VPPControl
vpp = VPPControl()
vpp.api.nat44_ed_plugin_enable_disable(enable=True)       # enable nat44 plugin
vpp.api.nat44_forwarding_enable_disable(enable=True)	  # enable forwarding
vpp.api.nat44_ed_add_del_output_interface(sw_if_index=1, is_add=True)		# enable output-feature on eth0 (outbound interface)
vpp.api.nat44_interface_add_del_feature(flags=0x20, sw_if_index=2, is_add=True)		# set inbound interface eth1
vpp.api.nat44_add_del_address_range(first_ip_address='192.168.122.55', last_ip_address='192.168.122.56', is_add=True)     # set translation pool
# vpp.api.nat44_interface_add_del_feature(flags=0x10, sw_if_index=1, is_add=True)         #  set outbound interface eth0 - for the second case

Details

Version
2025.03.18-0018-rolling
Is it a breaking change?
Unspecified (possibly destroys the router)
Issue type
Bug (incorrect behavior)