summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--interface-definitions/vpp.xml.in18
-rw-r--r--python/vyos/vpp/config_verify.py13
-rw-r--r--python/vyos/vpp/utils.py37
-rwxr-xr-xsmoketest/scripts/cli/test_vpp.py67
-rw-r--r--src/conf_mode/vpp_interfaces_gre.py11
-rw-r--r--src/conf_mode/vpp_interfaces_ipip.py11
-rw-r--r--src/conf_mode/vpp_interfaces_vxlan.py11
7 files changed, 151 insertions, 17 deletions
diff --git a/interface-definitions/vpp.xml.in b/interface-definitions/vpp.xml.in
index 150803a0d..e9075588e 100644
--- a/interface-definitions/vpp.xml.in
+++ b/interface-definitions/vpp.xml.in
@@ -14,7 +14,7 @@
<children>
<tagNode name="bonding" owner="${vyos_conf_scripts_dir}/vpp_interfaces_bonding.py">
<properties>
- <priority>304</priority>
+ <priority>324</priority>
<help>Bonding Interface/Link Aggregation</help>
<constraint>
<regex>bond[0-9]+</regex>
@@ -112,7 +112,7 @@
</tagNode>
<tagNode name="bridge" owner="${vyos_conf_scripts_dir}/vpp_interfaces_bridge.py">
<properties>
- <priority>307</priority>
+ <priority>327</priority>
<help>Bridge domain</help>
<constraint>
<!-- Bridge domain 0 is reserved to vpp default -->
@@ -159,7 +159,7 @@
<!-- Disable as geneve interface index in the VPP always 0 and not configured -->
<!-- <tagNode name="geneve" owner="${vyos_conf_scripts_dir}/vpp_interfaces_geneve.py">
<properties>
- <priority>305</priority>
+ <priority>325</priority>
<help>Generic Network Virtualization Encapsulation (GENEVE) Interface</help>
<constraint>
<regex>geneve[0-9]+</regex>
@@ -179,7 +179,7 @@
<!-- </tagNode> -->
<tagNode name="gre" owner="${vyos_conf_scripts_dir}/vpp_interfaces_gre.py">
<properties>
- <priority>305</priority>
+ <priority>325</priority>
<help>Generic Network Encapsulation (GRE) Interface</help>
<constraint>
<regex>gre[0-9]+</regex>
@@ -246,7 +246,7 @@
</tagNode>
<tagNode name="ipip" owner="${vyos_conf_scripts_dir}/vpp_interfaces_ipip.py">
<properties>
- <priority>305</priority>
+ <priority>325</priority>
<help>IP encapsulation tunnel interface</help>
<constraint>
<regex>ipip[0-9]+</regex>
@@ -267,7 +267,7 @@
</tagNode>
<tagNode name="loopback" owner="${vyos_conf_scripts_dir}/vpp_interfaces_loopback.py">
<properties>
- <priority>305</priority>
+ <priority>325</priority>
<help>Loopback Interface</help>
<constraint>
<regex>lo[0-9]+</regex>
@@ -286,7 +286,7 @@
</tagNode>
<tagNode name="vxlan" owner="${vyos_conf_scripts_dir}/vpp_interfaces_vxlan.py">
<properties>
- <priority>305</priority>
+ <priority>325</priority>
<help>Virtual Extensible LAN (VXLAN) Interface</help>
<constraint>
<regex>vxlan[0-9]+</regex>
@@ -309,7 +309,7 @@
<tagNode name="xconnect" owner="${vyos_conf_scripts_dir}/vpp_interfaces_xconnect.py">
<properties>
<help>Layer 2 cross connect</help>
- <priority>305</priority>
+ <priority>325</priority>
<constraint>
<regex>xcon[0-9]+</regex>
</constraint>
@@ -845,7 +845,7 @@
<tagNode name="kernel-interfaces" owner="${vyos_conf_scripts_dir}/vpp_kernel-interfaces.py">
<properties>
<help>VPP kernel interface settings</help>
- <priority>308</priority>
+ <priority>328</priority>
<valueHelp>
<format>vpptapN</format>
<description>Kernel interface name</description>
diff --git a/python/vyos/vpp/config_verify.py b/python/vyos/vpp/config_verify.py
index 6b35858d2..830d4af73 100644
--- a/python/vyos/vpp/config_verify.py
+++ b/python/vyos/vpp/config_verify.py
@@ -102,6 +102,19 @@ def verify_vpp_remove_xconnect_interface(config: dict):
)
+def verify_vpp_tunnel_source_address(config: dict):
+ from vyos.utils.network import is_intf_addr_assigned
+
+ address = config.get('source_address')
+ for iface in config.get('vpp_ether_vif_ifaces', []):
+ if is_intf_addr_assigned(iface, address):
+ return True
+
+ raise ConfigError(
+ f'Source address "{address}" is not assigned on any Ethernet or VIF interface!'
+ )
+
+
def verify_dev_driver(iface_name: str, driver_type: str) -> bool:
# Lists of drivers compatible with DPDK and XDP
drivers_dpdk: list[str] = [
diff --git a/python/vyos/vpp/utils.py b/python/vyos/vpp/utils.py
index 681d25578..fe08a98b8 100644
--- a/python/vyos/vpp/utils.py
+++ b/python/vyos/vpp/utils.py
@@ -85,6 +85,43 @@ def cli_ifaces_list(config_instance, mode: str = 'candidate') -> list[str]:
return vpp_ifaces
+def cli_ethernet_with_vifs_ifaces(config_instance) -> list[str]:
+ """List of all VPP Ethernet interfaces with VIFs
+
+ Args:
+ config_instance (VyOS Config): VyOS Config instance
+
+ Returns:
+ list[str]: list of interfaces
+ """
+ from vyos.configdict import get_interface_dict
+
+ # Read a config
+ config = config_instance.get_config_dict(
+ ['vpp'],
+ key_mangling=('-', '_'),
+ get_first_key=True,
+ no_tag_node_value_mangle=True,
+ with_recursive_defaults=True,
+ )
+
+ ifaces: list[str] = []
+
+ # Get a list of Ethernet interfaces
+ for iface in config.get('settings', {}).get('interface', {}).keys():
+ ifaces.append(iface)
+
+ # Add Ethernet interfaces with VIFs
+ for iface in ifaces:
+ _, iface_config = get_interface_dict(
+ config_instance, ['interfaces', 'ethernet'], ifname=iface
+ )
+ ifaces.extend([f'{iface}.{vif}' for vif in iface_config.get('vif', {})])
+ ifaces.extend([f'{iface}.{vif_s}' for vif_s in iface_config.get('vif_s', {})])
+
+ return ifaces
+
+
def vpp_ifaces_list(vpp_api) -> list[dict]:
"""List interfaces in VPP
diff --git a/smoketest/scripts/cli/test_vpp.py b/smoketest/scripts/cli/test_vpp.py
index 6c19fbba0..57f47067a 100755
--- a/smoketest/scripts/cli/test_vpp.py
+++ b/smoketest/scripts/cli/test_vpp.py
@@ -106,6 +106,10 @@ class TestVPP(VyOSUnitTestSHIM.TestCase):
self.cli_delete(base_path)
self.cli_commit()
+ # delete address for Ethernet interface
+ self.cli_delete(['interfaces', 'ethernet', interface, 'address'])
+ self.cli_commit()
+
self.assertFalse(os.path.exists(VPP_CONF))
self.assertFalse(process_named_running(PROCESS_NAME))
@@ -170,11 +174,21 @@ class TestVPP(VyOSUnitTestSHIM.TestCase):
base_path
+ ['interfaces', 'vxlan', interface_vxlan, 'source-address', source_address]
)
+ self.cli_set(base_path + ['interfaces', 'vxlan', interface_vxlan, 'vni', vni])
+
+ # remote and source address must not be the same
+ # expect raise ConfigError
+ self.cli_set(
+ base_path
+ + ['interfaces', 'vxlan', interface_vxlan, 'remote', source_address]
+ )
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+
self.cli_set(
base_path
+ ['interfaces', 'vxlan', interface_vxlan, 'remote', remote_address]
)
- self.cli_set(base_path + ['interfaces', 'vxlan', interface_vxlan, 'vni', vni])
self.cli_set(
base_path
+ [
@@ -214,6 +228,23 @@ class TestVPP(VyOSUnitTestSHIM.TestCase):
new_source_address,
]
)
+
+ # source address of the tunnel interface should be configured
+ # expect raise ConfigError
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+
+ self.cli_set(
+ [
+ 'interfaces',
+ 'ethernet',
+ interface,
+ 'vif',
+ vni,
+ 'address',
+ f'{new_source_address}/24',
+ ]
+ )
self.cli_commit()
# check gre interface after update
@@ -274,7 +305,11 @@ class TestVPP(VyOSUnitTestSHIM.TestCase):
self.assertFalse(os.path.isdir(f'/sys/class/net/{interface_kernel}'))
# delete vxlan interface
- self.cli_set(base_path + ['interfaces', 'vxlan', interface_vxlan])
+ self.cli_delete(base_path + ['interfaces', 'vxlan', interface_vxlan])
+ self.cli_commit()
+
+ # delete vif Ethernet interface
+ self.cli_delete(['interfaces', 'ethernet', interface, 'vif'])
self.cli_commit()
def test_03_vpp_gre(self):
@@ -302,6 +337,15 @@ class TestVPP(VyOSUnitTestSHIM.TestCase):
+ ['kernel-interfaces', interface_kernel, 'address', f'{kernel_address}/31']
)
+ # source address of the tunnel interface should be configured
+ # expect raise ConfigError
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+
+ self.cli_set(
+ ['interfaces', 'ethernet', interface, 'address', f'{source_address}/24']
+ )
+
# commit changes
self.cli_commit()
@@ -319,6 +363,10 @@ class TestVPP(VyOSUnitTestSHIM.TestCase):
base_path
+ ['interfaces', 'gre', interface_gre, 'source-address', new_source_address]
)
+
+ self.cli_set(
+ ['interfaces', 'ethernet', interface, 'address', f'{new_source_address}/24']
+ )
self.cli_commit()
# check gre interface after update
@@ -364,7 +412,7 @@ class TestVPP(VyOSUnitTestSHIM.TestCase):
self.assertFalse(os.path.isdir(f'/sys/class/net/{interface_kernel}'))
# delete gre interface
- self.cli_set(base_path + ['interfaces', 'gre', interface_gre])
+ self.cli_delete(base_path + ['interfaces', 'gre', interface_gre])
self.cli_commit()
@unittest.skip('Skipping this test geneve index always is 0')
@@ -566,7 +614,7 @@ class TestVPP(VyOSUnitTestSHIM.TestCase):
self.assertFalse(os.path.isdir(f'/sys/class/net/{interface_kernel}'))
# delete loopback interface
- self.cli_set(base_path + ['interfaces', 'loopback', interface_loopback])
+ self.cli_delete(base_path + ['interfaces', 'loopback', interface_loopback])
self.cli_commit()
@unittest.skip('Skipping temporary bonding, sometimes get recursion T7117')
@@ -900,6 +948,15 @@ class TestVPP(VyOSUnitTestSHIM.TestCase):
new_source_address,
]
)
+
+ # source address of the tunnel interface should be configured
+ # expect raise ConfigError
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+
+ self.cli_set(
+ ['interfaces', 'ethernet', interface, 'address', f'{new_source_address}/24']
+ )
self.cli_commit()
# check ipip interface after update
@@ -951,7 +1008,7 @@ class TestVPP(VyOSUnitTestSHIM.TestCase):
self.assertFalse(os.path.isdir(f'/sys/class/net/{interface_kernel}'))
# delete ipip interface
- self.cli_set(base_path + ['interfaces', 'ipip', interface_ipip])
+ self.cli_delete(base_path + ['interfaces', 'ipip', interface_ipip])
self.cli_commit()
def test_09_vpp_xconnect(self):
diff --git a/src/conf_mode/vpp_interfaces_gre.py b/src/conf_mode/vpp_interfaces_gre.py
index de7398248..823f3ff4d 100644
--- a/src/conf_mode/vpp_interfaces_gre.py
+++ b/src/conf_mode/vpp_interfaces_gre.py
@@ -32,8 +32,9 @@ from vyos.vpp.config_verify import (
verify_vpp_change_kernel_interface,
verify_vpp_remove_xconnect_interface,
verify_vpp_exists_kernel_interface,
+ verify_vpp_tunnel_source_address,
)
-from vyos.vpp.utils import cli_ifaces_lcp_kernel_list
+from vyos.vpp.utils import cli_ifaces_lcp_kernel_list, cli_ethernet_with_vifs_ifaces
def get_config(config=None) -> dict:
@@ -94,6 +95,9 @@ def get_config(config=None) -> dict:
# list of all kernel interfaces `vpp interface xxx kernel-interface xxx`
config['candidate_kernel_interfaces'] = cli_ifaces_lcp_kernel_list(conf)
+ # list of all Ethernet interfaces with vifs
+ config['vpp_ether_vif_ifaces'] = cli_ethernet_with_vifs_ifaces(conf)
+
# Dependency
config['xconn_members'] = deps_xconnect_dict(conf)
if ifname in config['xconn_members']:
@@ -130,6 +134,11 @@ def verify(config):
f"Required options are missing: {', '.join(missing_keys).replace('_', '-')}"
)
+ # verify source address and remote address
+ verify_vpp_tunnel_source_address(config)
+ if config.get('source_address') == config.get('remote'):
+ raise ConfigError('Remote address must not be the same as source address')
+
# check multipoint mode
if config.get('mode') == 'point-to-multipoint':
# For multipoint mode, remote IP must be 0.0.0.0
diff --git a/src/conf_mode/vpp_interfaces_ipip.py b/src/conf_mode/vpp_interfaces_ipip.py
index 2428a9850..c52e7c997 100644
--- a/src/conf_mode/vpp_interfaces_ipip.py
+++ b/src/conf_mode/vpp_interfaces_ipip.py
@@ -31,8 +31,9 @@ from vyos.vpp.config_verify import (
verify_vpp_change_kernel_interface,
verify_vpp_remove_xconnect_interface,
verify_vpp_exists_kernel_interface,
+ verify_vpp_tunnel_source_address,
)
-from vyos.vpp.utils import cli_ifaces_lcp_kernel_list
+from vyos.vpp.utils import cli_ifaces_lcp_kernel_list, cli_ethernet_with_vifs_ifaces
def get_config(config=None) -> dict:
@@ -93,6 +94,9 @@ def get_config(config=None) -> dict:
# list of all kernel interfaces `vpp interface xxx kernel-interface xxx`
config['candidate_kernel_interfaces'] = cli_ifaces_lcp_kernel_list(conf)
+ # list of all Ethernet interfaces with vifs
+ config['vpp_ether_vif_ifaces'] = cli_ethernet_with_vifs_ifaces(conf)
+
# Dependency
config['xconn_members'] = deps_xconnect_dict(conf)
if ifname in config['xconn_members']:
@@ -130,6 +134,11 @@ def verify(config):
f"Required options are missing: {', '.join(missing_keys).replace('_', '-')}"
)
+ # verify source address and remote address
+ verify_vpp_tunnel_source_address(config)
+ if config.get('source_address') == config.get('remote'):
+ raise ConfigError('Remote address must not be the same as source address')
+
# Change 'vpp interfaces ipip ipipX kernel-interface vpp-tunX'
# => 'vpp interfaces ipip ipipX kernel-interface vpp-tunY'
# check if we have kernel interface config 'vpp kernel-interface vpp-tunX'
diff --git a/src/conf_mode/vpp_interfaces_vxlan.py b/src/conf_mode/vpp_interfaces_vxlan.py
index b94b39d6d..963cd90ec 100644
--- a/src/conf_mode/vpp_interfaces_vxlan.py
+++ b/src/conf_mode/vpp_interfaces_vxlan.py
@@ -33,8 +33,9 @@ from vyos.vpp.config_verify import (
verify_vpp_change_kernel_interface,
verify_vpp_remove_xconnect_interface,
verify_vpp_exists_kernel_interface,
+ verify_vpp_tunnel_source_address,
)
-from vyos.vpp.utils import cli_ifaces_lcp_kernel_list
+from vyos.vpp.utils import cli_ifaces_lcp_kernel_list, cli_ethernet_with_vifs_ifaces
def get_config(config=None) -> dict:
@@ -95,6 +96,9 @@ def get_config(config=None) -> dict:
# list of all kernel interfaces `vpp interface xxx kernel-interface xxx`
config['candidate_kernel_interfaces'] = cli_ifaces_lcp_kernel_list(conf)
+ # list of all Ethernet interfaces with vifs
+ config['vpp_ether_vif_ifaces'] = cli_ethernet_with_vifs_ifaces(conf)
+
# Dependency
config['xconn_members'] = deps_xconnect_dict(conf)
if ifname in config['xconn_members']:
@@ -134,6 +138,11 @@ def verify(config):
f"Required options are missing: {', '.join(missing_keys).replace('_', '-')}"
)
+ # verify source address and remote address
+ verify_vpp_tunnel_source_address(config)
+ if config.get('source_address') == config.get('remote'):
+ raise ConfigError('Remote address must not be the same as source address')
+
# Change 'vpp interfaces vxlan greX kernel-interface vpp-tunX'
# => 'vpp interfaces gre vxlanX kernel-interface vpp-tunY'
# check if we have kernel interface config 'vpp kernel-interface vpp-tunX'