From 10701108fecb36f7be7eb7ef5f1e54e63da5fb4e Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Wed, 20 Dec 2023 22:25:47 +0100 Subject: vrf: T591: define sysctl setting for net.vrf.strict_mode Enable/Disable VRF strict mode, when net.vrf.strict_mode=0 (default) it is possible to associate multiple VRF devices to the same table. Conversely, when net.vrf.strict_mode=1 a table can be associated to a single VRF device. A VRF table can be used by the VyOS CLI only once (ensured by verify()), this simply adds an additional Kernel safety net, but a requirement for IPv6 segment routing headers. --- smoketest/scripts/cli/test_vrf.py | 21 +++++++++++++-------- src/conf_mode/vrf.py | 12 ++++++++++++ src/etc/sysctl.d/30-vyos-router.conf | 8 -------- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/smoketest/scripts/cli/test_vrf.py b/smoketest/scripts/cli/test_vrf.py index bb91eddea..6207a1b41 100755 --- a/smoketest/scripts/cli/test_vrf.py +++ b/smoketest/scripts/cli/test_vrf.py @@ -30,6 +30,7 @@ from vyos.utils.process import cmd from vyos.utils.file import read_file from vyos.utils.network import get_interface_config from vyos.utils.network import is_intf_addr_assigned +from vyos.utils.system import sysctl_read base_path = ['vrf'] vrfs = ['red', 'green', 'blue', 'foo-bar', 'baz_foo'] @@ -58,6 +59,8 @@ class VRFTest(VyOSUnitTestSHIM.TestCase): self.cli_commit() for vrf in vrfs: self.assertNotIn(vrf, interfaces()) + # If there is no VRF defined, strict_mode should be off + self.assertEqual(sysctl_read('net.vrf.strict_mode'), '0') def test_vrf_vni_and_table_id(self): base_table = '1000' @@ -130,8 +133,9 @@ class VRFTest(VyOSUnitTestSHIM.TestCase): # Ensure VRF was created self.assertIn(vrf, interfaces()) # Verify IP forwarding is 1 (enabled) - self.assertEqual(read_file(f'/proc/sys/net/ipv4/conf/{vrf}/forwarding'), '1') - self.assertEqual(read_file(f'/proc/sys/net/ipv6/conf/{vrf}/forwarding'), '1') + self.assertEqual(sysctl_read(f'net.ipv4.conf.{vrf}.forwarding'), '1') + self.assertEqual(sysctl_read(f'net.ipv6.conf.{vrf}.forwarding'), '1') + # Test for proper loopback IP assignment for addr in loopbacks: self.assertTrue(is_intf_addr_assigned(vrf, addr)) @@ -149,10 +153,11 @@ class VRFTest(VyOSUnitTestSHIM.TestCase): self.cli_commit() # Verify VRF configuration - tmp = read_file('/proc/sys/net/ipv4/tcp_l3mdev_accept') - self.assertIn(tmp, '1') - tmp = read_file('/proc/sys/net/ipv4/udp_l3mdev_accept') - self.assertIn(tmp, '1') + self.assertEqual(sysctl_read('net.ipv4.tcp_l3mdev_accept'), '1') + self.assertEqual(sysctl_read('net.ipv4.udp_l3mdev_accept'), '1') + + # If there is any VRF defined, strict_mode should be on + self.assertEqual(sysctl_read('net.vrf.strict_mode'), '1') def test_vrf_table_id_is_unalterable(self): # Linux Kernel prohibits the change of a VRF table on the fly. @@ -290,8 +295,8 @@ class VRFTest(VyOSUnitTestSHIM.TestCase): # Ensure VRF was created self.assertIn(vrf, interfaces()) # Verify IP forwarding is 0 (disabled) - self.assertEqual(read_file(f'/proc/sys/net/ipv4/conf/{vrf}/forwarding'), '0') - self.assertEqual(read_file(f'/proc/sys/net/ipv6/conf/{vrf}/forwarding'), '0') + self.assertEqual(sysctl_read(f'net.ipv4.conf.{vrf}.forwarding'), '0') + self.assertEqual(sysctl_read(f'net.ipv6.conf.{vrf}.forwarding'), '0') def test_vrf_ip_protocol_route_map(self): table = '6000' diff --git a/src/conf_mode/vrf.py b/src/conf_mode/vrf.py index 37625142c..9b1b6355f 100755 --- a/src/conf_mode/vrf.py +++ b/src/conf_mode/vrf.py @@ -214,6 +214,18 @@ def apply(vrf): # Delete the VRF Kernel interface call(f'ip link delete dev {tmp}') + # Enable/Disable VRF strict mode + # When net.vrf.strict_mode=0 (default) it is possible to associate multiple + # VRF devices to the same table. Conversely, when net.vrf.strict_mode=1 a + # table can be associated to a single VRF device. + # + # A VRF table can be used by the VyOS CLI only once (ensured by verify()), + # this simply adds an additional Kernel safety net + strict_mode = '0' + # Set to 1 if any VRF is defined + if 'name' in vrf: strict_mode = '1' + sysctl_write('net.vrf.strict_mode', strict_mode) + if 'name' in vrf: # Separate VRFs in conntrack table # check if table already exists diff --git a/src/etc/sysctl.d/30-vyos-router.conf b/src/etc/sysctl.d/30-vyos-router.conf index 67d96969e..1c9b8999f 100644 --- a/src/etc/sysctl.d/30-vyos-router.conf +++ b/src/etc/sysctl.d/30-vyos-router.conf @@ -105,11 +105,3 @@ net.core.rps_sock_flow_entries = 32768 net.core.default_qdisc=fq_codel net.ipv4.tcp_congestion_control=bbr -# VRF - Virtual routing and forwarding -# When net.vrf.strict_mode=0 (default) it is possible to associate multiple -# VRF devices to the same table. Conversely, when net.vrf.strict_mode=1 a -# table can be associated to a single VRF device. -# -# A VRF table can be used by the VyOS CLI only once (ensured by verify()), -# this simply adds an additional Kernel safety net -net.vrf.strict_mode=1 -- cgit v1.2.3