summaryrefslogtreecommitdiff
path: root/smoketest/scripts/cli
diff options
context:
space:
mode:
authorChristian Breunig <christian@breunig.cc>2025-10-17 22:02:37 +0200
committerChristian Breunig <christian@breunig.cc>2025-10-17 22:02:37 +0200
commit186900f7165b298ed4b24d0c6b795e50a01ebbdb (patch)
tree5113b998595e02b54bf7fe22c07bc43c167ac81f /smoketest/scripts/cli
parent7c62df1f49bf539aa69fbbedd15656c01d47c17c (diff)
downloadvyos-1x-186900f7165b298ed4b24d0c6b795e50a01ebbdb.tar.gz
vyos-1x-186900f7165b298ed4b24d0c6b795e50a01ebbdb.zip
smoketest: T7927: test DHCP route preservation
This complements commit cf4666257 ("frrender: T7927: de-nest DHCP and PPPoE interface section for VRFs") by validating the new DHCP behavior. When a VRF bound interface obtains an IP via DHCP, the default route received must be reflected in FRR's routing table (vtysh). Ensure the dynamic DHCP learned route is retained even when unrelated sections of the FRR configuration are modified.
Diffstat (limited to 'smoketest/scripts/cli')
-rwxr-xr-xsmoketest/scripts/cli/test_vrf.py58
1 files changed, 58 insertions, 0 deletions
diff --git a/smoketest/scripts/cli/test_vrf.py b/smoketest/scripts/cli/test_vrf.py
index a69068c6e..3a3f0e5b9 100755
--- a/smoketest/scripts/cli/test_vrf.py
+++ b/smoketest/scripts/cli/test_vrf.py
@@ -20,6 +20,7 @@ import unittest
from json import loads
from jmespath import search
+from time import sleep
from base_vyostest_shim import VyOSUnitTestSHIM
@@ -35,6 +36,7 @@ from vyos.utils.process import cmd
from vyos.utils.system import sysctl_read
from vyos.template import inc_ip
from vyos.utils.process import process_named_running
+from vyos.xml_ref import default_value
base_path = ['vrf']
vrfs = ['red', 'green', 'blue', 'foo-bar', 'baz_foo']
@@ -773,6 +775,62 @@ class VRFTest(VyOSUnitTestSHIM.TestCase):
self.cli_delete(base)
self.cli_commit()
+ def test_dhcp_vrf_default_route(self):
+ # T7927 - when retrieving a default route via DHCP, check that additional
+ # calls into FRRender() keep the DHCP route in place
+
+ vrf_name = 'red15'
+ default_gateway = '192.0.2.1'
+ dhcp_if_server = 'veth0'
+ dhcp_if_client = 'veth1'
+
+ default_distance = default_value(['interfaces', 'virtual-ethernet',
+ dhcp_if_client, 'dhcp-options',
+ 'default-route-distance'])
+
+ dhcp_pool_base = ['service', 'dhcp-server', 'shared-network-name',
+ 'FOO-4', 'subnet', '192.0.2.0/24']
+ veth_base = ['interfaces', 'virtual-ethernet']
+
+ # Start DHCP Server in VRF connected via veth pair to default VRF
+ self.cli_set(['vrf', 'name', vrf_name, 'table', '48752'])
+ self.cli_set(veth_base + [dhcp_if_server, 'address', '192.0.2.1/24'])
+ self.cli_set(veth_base + [dhcp_if_server, 'peer-name', dhcp_if_client])
+ self.cli_set(veth_base + [dhcp_if_client, 'peer-name', dhcp_if_server])
+ self.cli_set(veth_base + [dhcp_if_client, 'vrf', vrf_name])
+
+ self.cli_set(['service', 'dhcp-server', 'listen-interface', dhcp_if_server])
+ self.cli_set(dhcp_pool_base + ['option', 'default-router', default_gateway])
+ self.cli_set(dhcp_pool_base + ['range', 'uno', 'start', '192.0.2.10'])
+ self.cli_set(dhcp_pool_base + ['range', 'uno', 'stop', '192.0.2.30'])
+ self.cli_set(dhcp_pool_base + ['subnet-id', '1'])
+
+ self.cli_commit()
+
+ # Start DHCP client in VRF
+ self.cli_set(['interfaces', 'virtual-ethernet', dhcp_if_client, 'address', 'dhcp'])
+ self.cli_commit()
+
+ # We need to wait until DHCP client has started and an IP address has been received
+ sleep(8)
+
+ frrconfig = self.getFRRconfig('^vrf red', stop_section='^exit-vrf')
+ self.assertIn(f' ip route 0.0.0.0/0 {default_gateway} {dhcp_if_client} '\
+ f'tag 210 {default_distance}', frrconfig)
+
+ # Change anything in FRR to re-trigger config generation. DHCP route
+ # must still be present
+ self.cli_set(['protocols', 'static', 'route', '10.0.0.0/24', 'blackhole'])
+ self.cli_commit()
+
+ frrconfig = self.getFRRconfig('^vrf red', stop_section='^exit-vrf')
+ self.assertIn(f' ip route 0.0.0.0/0 {default_gateway} {dhcp_if_client} '\
+ f'tag 210 {default_distance}', frrconfig)
+
+ self.cli_delete(['interfaces', 'virtual-ethernet'])
+ self.cli_delete(['service', 'dhcp-server'])
+ self.cli_delete(['vrf', 'name', vrf_name])
+
def test_dhcpv6_single_pool(self):
# Prepare the vrf and other options
table = '100'