From 0ecddff7cffa8900d351d5c15e32420f9d780c0b Mon Sep 17 00:00:00 2001 From: Andreas Date: Wed, 29 Dec 2021 18:02:06 +0100 Subject: vxlan: T4120: add ability to set multiple remotes (PR #1127) VXLAN does support using multiple remotes but VyOS does not. Add the ability to set multiple remotes and add their flood lists using "bridge" command. --- .../include/interface/tunnel-remote.xml.i | 2 +- .../include/interface/tunnel-remotes.xml.i | 19 ++++++++++++ interface-definitions/interfaces-vxlan.xml.in | 2 +- python/vyos/ifconfig/vxlan.py | 7 +++++ smoketest/scripts/cli/test_interfaces_vxlan.py | 2 ++ src/conf_mode/interfaces-vxlan.py | 34 ++++++++++++++++++++++ 6 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 interface-definitions/include/interface/tunnel-remotes.xml.i diff --git a/interface-definitions/include/interface/tunnel-remote.xml.i b/interface-definitions/include/interface/tunnel-remote.xml.i index 1ba9b0382..2a8891b85 100644 --- a/interface-definitions/include/interface/tunnel-remote.xml.i +++ b/interface-definitions/include/interface/tunnel-remote.xml.i @@ -1,4 +1,4 @@ - + Tunnel remote address diff --git a/interface-definitions/include/interface/tunnel-remotes.xml.i b/interface-definitions/include/interface/tunnel-remotes.xml.i new file mode 100644 index 000000000..ae8481898 --- /dev/null +++ b/interface-definitions/include/interface/tunnel-remotes.xml.i @@ -0,0 +1,19 @@ + + + + Tunnel remote address + + ipv4 + Tunnel remote IPv4 address + + + ipv6 + Tunnel remote IPv6 address + + + + + + + + diff --git a/interface-definitions/interfaces-vxlan.xml.in b/interface-definitions/interfaces-vxlan.xml.in index 4c3c3ac71..559067ea5 100644 --- a/interface-definitions/interfaces-vxlan.xml.in +++ b/interface-definitions/interfaces-vxlan.xml.in @@ -98,7 +98,7 @@ #include #include - #include + #include #include #include diff --git a/python/vyos/ifconfig/vxlan.py b/python/vyos/ifconfig/vxlan.py index 0c5282db4..87b5e40b8 100644 --- a/python/vyos/ifconfig/vxlan.py +++ b/python/vyos/ifconfig/vxlan.py @@ -82,3 +82,10 @@ class VXLANIf(Interface): self._cmd(cmd.format(**self.config)) # interface is always A/D down. It needs to be enabled explicitly self.set_admin_state('down') + + other_remotes = self.config.get('other_remotes') + if other_remotes: + for rem in other_remotes: + self.config['rem'] = rem + cmd2 = 'bridge fdb append to 00:00:00:00:00:00 dst {rem} port {port} dev {ifname}' + self._cmd(cmd2.format(**self.config)) diff --git a/smoketest/scripts/cli/test_interfaces_vxlan.py b/smoketest/scripts/cli/test_interfaces_vxlan.py index 9278adadd..12fc463ba 100755 --- a/smoketest/scripts/cli/test_interfaces_vxlan.py +++ b/smoketest/scripts/cli/test_interfaces_vxlan.py @@ -33,6 +33,8 @@ class VXLANInterfaceTest(BasicInterfaceTest.TestCase): 'vxlan10': ['vni 10', 'remote 127.0.0.2'], 'vxlan20': ['vni 20', 'group 239.1.1.1', 'source-interface eth0'], 'vxlan30': ['vni 30', 'remote 2001:db8:2000::1', 'source-address 2001:db8:1000::1', 'parameters ipv6 flowlabel 0x1000'], + 'vxlan40': ['vni 40', 'remote 127.0.0.2', 'remote 127.0.0.3'], + 'vxlan50': ['vni 50', 'remote 2001:db8:2000::1', 'remote 2001:db8:2000::2', 'parameters ipv6 flowlabel 0x1000'], } cls._interfaces = list(cls._options) # call base-classes classmethod diff --git a/src/conf_mode/interfaces-vxlan.py b/src/conf_mode/interfaces-vxlan.py index 1f097c4e3..092f249df 100755 --- a/src/conf_mode/interfaces-vxlan.py +++ b/src/conf_mode/interfaces-vxlan.py @@ -58,6 +58,13 @@ def get_config(config=None): if len(vxlan['other_tunnels']) == 0: del vxlan['other_tunnels'] + # leave first remote in dict and put the other ones (if they exists) to "other_remotes" + remotes = vxlan.get('remote') + if remotes: + vxlan['remote'] = remotes[0] + if len(remotes) > 1: + del remotes[0] + vxlan['other_remotes'] = remotes return vxlan def verify(vxlan): @@ -108,6 +115,33 @@ def verify(vxlan): raise ConfigError(f'Underlaying device MTU is to small ({lower_mtu} '\ f'bytes) for VXLAN overhead ({vxlan_overhead} bytes!)') + # Check for mixed IPv4 and IPv6 addresses + protocol = None + if 'source_address' in vxlan: + if is_ipv6(vxlan['source_address']): + protocol = 'ipv6' + else: + protocol = 'ipv4' + if 'remote' in vxlan: + if is_ipv6(vxlan['remote']): + if protocol == 'ipv4': + raise ConfigError('IPv4 and IPV6 cannot be mixed') + protocol = 'ipv6' + else: + if protocol == 'ipv6': + raise ConfigError('IPv4 and IPV6 cannot be mixed') + protocol = 'ipv4' + if 'other_remotes' in vxlan: + for rem in vxlan['other_remotes']: + if is_ipv6(rem): + if protocol == 'ipv4': + raise ConfigError('IPv4 and IPV6 cannot be mixed') + protocol = 'ipv6' + else: + if protocol == 'ipv6': + raise ConfigError('IPv4 and IPV6 cannot be mixed') + protocol = 'ipv4' + verify_mtu_ipv6(vxlan) verify_address(vxlan) return None -- cgit v1.2.3