From adf968ab142c12cb8f53e207aafcc0ccb67e28c5 Mon Sep 17 00:00:00 2001 From: Viacheslav Hletenko Date: Tue, 3 Jun 2025 17:13:47 +0300 Subject: T7503: Add VPP smoketest of NAT44 and CGNAT (#35) --- smoketest/scripts/cli/test_vpp.py | 116 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/smoketest/scripts/cli/test_vpp.py b/smoketest/scripts/cli/test_vpp.py index 57f47067a..7a150f7e8 100755 --- a/smoketest/scripts/cli/test_vpp.py +++ b/smoketest/scripts/cli/test_vpp.py @@ -1269,6 +1269,122 @@ class TestVPP(VyOSUnitTestSHIM.TestCase): config = read_file(VPP_CONF) self.assertIn('interface ipip', config) + def test_16_vpp_cgnat(self): + base_cgnat = base_path + ['nat', 'cgnat'] + iface_out = 'eth0' + iface_inside = 'eth1' + timeout_udp = '150' + timeout_icmp = '30' + timeout_tcp_est = '600' + timeout_tcp_trans = '120' + inside_prefix = '100.64.0.0/24' + outside_prefix = '192.0.2.1/32' + + self.cli_set(base_path + ['settings', 'interface', iface_out, 'driver', driver]) + self.cli_set(base_cgnat + ['interface', 'inside', iface_inside]) + self.cli_set(base_cgnat + ['interface', 'outside', iface_out]) + self.cli_set(base_cgnat + ['rule', '100', 'inside-prefix', inside_prefix]) + self.cli_set(base_cgnat + ['rule', '100', 'outside-prefix', outside_prefix]) + self.cli_set(base_cgnat + ['timeout', 'icmp', timeout_icmp]) + self.cli_set(base_cgnat + ['timeout', 'tcp-established', timeout_tcp_est]) + self.cli_set(base_cgnat + ['timeout', 'tcp-transitory', timeout_tcp_trans]) + self.cli_set(base_cgnat + ['timeout', 'udp', timeout_udp]) + self.cli_commit() + + # Check interfaces + _, out = rc_cmd('sudo vppctl show det44 interfaces') + self.assertIn(f'{iface_inside} in', out) + self.assertIn(f'{iface_out} out', out) + + # Check mappings + _, out = rc_cmd('sudo vppctl show det44 mappings') + self.assertIn(inside_prefix, out) + self.assertIn(outside_prefix, out) + + # Check timeouts + _, out = rc_cmd('sudo vppctl show det44 timeouts') + self.assertIn(f'udp timeout: {timeout_udp}sec', out) + self.assertIn(f'tcp established timeout: {timeout_tcp_est}sec', out) + self.assertIn(f'tcp transitory timeout: {timeout_tcp_trans}sec', out) + self.assertIn(f'icmp timeout: {timeout_icmp}sec', out) + + def test_17_vpp_nat(self): + base_nat = base_path + ['nat44'] + base_nat_settings = base_path + ['settings', 'nat44'] + exclude_local_addr = '100.64.0.52' + exclude_local_port = '22' + iface_out = 'eth0' + iface_inside = 'eth1' + timeout_udp = '150' + timeout_icmp = '30' + timeout_tcp_est = '600' + timeout_tcp_trans = '120' + translation_pool = '192.0.2.1-192.0.2.2' + static_ext_addr = '192.0.2.55' + static_local_addr = '100.64.0.55' + sess_limit = '64000' + + self.cli_set(base_path + ['settings', 'interface', iface_out, 'driver', driver]) + self.cli_set(base_nat + ['interface', 'inside', iface_inside]) + self.cli_set(base_nat + ['interface', 'outside', iface_out]) + self.cli_set( + base_nat + ['address-pool', 'translation', 'address', translation_pool] + ) + self.cli_set( + base_nat + ['exclude', 'rule', '100', 'local-address', exclude_local_addr] + ) + self.cli_set( + base_nat + ['exclude', 'rule', '100', 'local-port', exclude_local_port] + ) + self.cli_set( + base_nat + ['static', 'rule', '100', 'external', 'address', static_ext_addr] + ) + self.cli_set( + base_nat + ['static', 'rule', '100', 'local', 'address', static_local_addr] + ) + + self.cli_set(base_nat_settings + ['no-forwarding']) + self.cli_set(base_nat_settings + ['session-limit', sess_limit]) + self.cli_set(base_nat_settings + ['timeout', 'icmp', timeout_icmp]) + self.cli_set( + base_nat_settings + ['timeout', 'tcp-established', timeout_tcp_est] + ) + self.cli_set( + base_nat_settings + ['timeout', 'tcp-transitory', timeout_tcp_trans] + ) + self.cli_set(base_nat_settings + ['timeout', 'udp', timeout_udp]) + self.cli_commit() + + # Check addresses + _, out = rc_cmd('sudo vppctl show nat44 addresses') + self.assertIn(translation_pool.split('-')[0], out) + self.assertIn(translation_pool.split('-')[1], out) + + # Check interfaces + _, out = rc_cmd('sudo vppctl show nat44 interfaces') + self.assertIn(f'{iface_inside} in', out) + self.assertIn(f'{iface_out} out', out) + + # Check mappings + _, out = rc_cmd('sudo vppctl show nat44 static mappings') + self.assertIn( + f'local {static_local_addr} external {static_ext_addr} vrf 0', out + ) + self.assertIn(f'{exclude_local_addr}:{exclude_local_port} vrf 0', out) + + # Check timeouts + # skipped due to https://vyos.dev/T7515 + # + # _, out = rc_cmd('sudo vppctl show nat44 ei timeouts') + # self.assertIn(f'udp timeout: {timeout_udp}sec', out) + # self.assertIn(f'tcp established timeout: {timeout_tcp_est}sec', out) + # self.assertIn(f'tcp transitory timeout: {timeout_tcp_trans}sec', out) + # self.assertIn(f'icmp timeout: {timeout_icmp}sec', out) + + # Summary + _, out = rc_cmd('sudo vppctl show nat44 summary') + self.assertIn(f'max translations per thread: {sess_limit} fib 0', out) + if __name__ == '__main__': unittest.main(verbosity=2) -- cgit v1.2.3 From 983d296eafe97a21cf2c326aa1267edfd5308d37 Mon Sep 17 00:00:00 2001 From: Nataliia Solomko Date: Thu, 5 Jun 2025 11:32:41 +0300 Subject: T7515: Fix VPP NAT44 timeouts --- python/vyos/vpp/control_vpp.py | 19 ------------------- python/vyos/vpp/nat/nat44.py | 9 +++++++++ smoketest/scripts/cli/test_vpp.py | 12 +++++------- src/conf_mode/vpp.py | 7 ------- src/conf_mode/vpp_nat.py | 15 +++++++++++++++ 5 files changed, 29 insertions(+), 33 deletions(-) diff --git a/python/vyos/vpp/control_vpp.py b/python/vyos/vpp/control_vpp.py index 5db0ea560..5959b68b5 100644 --- a/python/vyos/vpp/control_vpp.py +++ b/python/vyos/vpp/control_vpp.py @@ -448,25 +448,6 @@ class VPPControl: """ self.__vpp_api_client.api.nat44_forwarding_enable_disable(enable=enable) - @_Decorators.api_call - def set_nat_timeouts( - self, icmp: int, udp: int, tcp_established: int, tcp_transitory: int - ) -> None: - """Set NAT timeouts - - Args: - tcp_established (int): TCP established timeout - tcp_transitory (int): TCP transitory timeout - udp (int): UDP timeout - icmp (int): ICMP timeout - """ - self.__vpp_api_client.api.nat_set_timeouts( - icmp=icmp, - udp=udp, - tcp_established=tcp_established, - tcp_transitory=tcp_transitory, - ) - @_Decorators.api_call def set_nat44_session_limit(self, session_limit: int) -> None: """Set NAT44 session limit diff --git a/python/vyos/vpp/nat/nat44.py b/python/vyos/vpp/nat/nat44.py index e01e05153..6b02688aa 100644 --- a/python/vyos/vpp/nat/nat44.py +++ b/python/vyos/vpp/nat/nat44.py @@ -215,6 +215,15 @@ class Nat44: is_add=False, ) + def set_nat_timeouts(self, icmp, udp, tcp_established, tcp_transitory): + """Set NAT timeouts""" + self.vpp.api.nat_set_timeouts( + icmp=icmp, + udp=udp, + tcp_established=tcp_established, + tcp_transitory=tcp_transitory, + ) + def enable_ipfix(self): """Enable NAT44 IPFIX logging""" self.vpp.api.nat44_ei_ipfix_enable_disable(enable=True) diff --git a/smoketest/scripts/cli/test_vpp.py b/smoketest/scripts/cli/test_vpp.py index 7a150f7e8..d8f7f3473 100755 --- a/smoketest/scripts/cli/test_vpp.py +++ b/smoketest/scripts/cli/test_vpp.py @@ -1373,13 +1373,11 @@ class TestVPP(VyOSUnitTestSHIM.TestCase): self.assertIn(f'{exclude_local_addr}:{exclude_local_port} vrf 0', out) # Check timeouts - # skipped due to https://vyos.dev/T7515 - # - # _, out = rc_cmd('sudo vppctl show nat44 ei timeouts') - # self.assertIn(f'udp timeout: {timeout_udp}sec', out) - # self.assertIn(f'tcp established timeout: {timeout_tcp_est}sec', out) - # self.assertIn(f'tcp transitory timeout: {timeout_tcp_trans}sec', out) - # self.assertIn(f'icmp timeout: {timeout_icmp}sec', out) + _, out = rc_cmd('sudo vppctl show nat timeouts') + self.assertIn(f'udp timeout: {timeout_udp}sec', out) + self.assertIn(f'tcp-established timeout: {timeout_tcp_est}sec', out) + self.assertIn(f'tcp-transitory timeout: {timeout_tcp_trans}sec', out) + self.assertIn(f'icmp timeout: {timeout_icmp}sec', out) # Summary _, out = rc_cmd('sudo vppctl show nat44 summary') diff --git a/src/conf_mode/vpp.py b/src/conf_mode/vpp.py index ed0e80c2c..029adbdec 100755 --- a/src/conf_mode/vpp.py +++ b/src/conf_mode/vpp.py @@ -745,13 +745,6 @@ def apply(config): enable_forwarding = False vpp_control.enable_disable_nat44_forwarding(enable_forwarding) - vpp_control.set_nat_timeouts( - icmp=int(nat44_settings.get('timeout').get('icmp')), - udp=int(nat44_settings.get('timeout').get('udp')), - tcp_established=int(nat44_settings.get('timeout').get('tcp_established')), - tcp_transitory=int(nat44_settings.get('timeout').get('tcp_transitory')), - ) - vpp_control.set_nat44_session_limit(int(nat44_settings.get('session_limit'))) if nat44_settings.get('workers'): diff --git a/src/conf_mode/vpp_nat.py b/src/conf_mode/vpp_nat.py index a6bc70032..77b9400e3 100644 --- a/src/conf_mode/vpp_nat.py +++ b/src/conf_mode/vpp_nat.py @@ -104,6 +104,14 @@ def get_config(config=None) -> dict: } ) + if conf.exists(['vpp', 'settings', 'nat44', 'timeout']): + timeouts = conf.get_config_dict( + ['vpp', 'settings', 'nat44', 'timeout'], + key_mangling=('-', '_'), + with_defaults=True, + ) + config.update(timeouts) + if effective_config: config.update({'effective': effective_config}) @@ -453,6 +461,13 @@ def apply(config): port=int(rule_config.get('local_port', 0)), interface=rule_config.get('external_interface'), ) + if 'timeout' in config: + n.set_nat_timeouts( + icmp=int(config.get('timeout').get('icmp')), + udp=int(config.get('timeout').get('udp')), + tcp_established=int(config.get('timeout').get('tcp_established')), + tcp_transitory=int(config.get('timeout').get('tcp_transitory')), + ) if __name__ == '__main__': -- cgit v1.2.3