diff options
Diffstat (limited to 'python/vyos')
-rw-r--r-- | python/vyos/ifconfig/vxlan.py | 21 | ||||
-rw-r--r-- | python/vyos/utils/network.py | 33 |
2 files changed, 48 insertions, 6 deletions
diff --git a/python/vyos/ifconfig/vxlan.py b/python/vyos/ifconfig/vxlan.py index 8c5a0220e..23b6daa3a 100644 --- a/python/vyos/ifconfig/vxlan.py +++ b/python/vyos/ifconfig/vxlan.py @@ -22,6 +22,7 @@ from vyos.utils.assertion import assert_list from vyos.utils.dict import dict_search from vyos.utils.network import get_interface_config from vyos.utils.network import get_vxlan_vlan_tunnels +from vyos.utils.network import get_vxlan_vni_filter @Interface.register class VXLANIf(Interface): @@ -79,6 +80,7 @@ class VXLANIf(Interface): 'parameters.ip.ttl' : 'ttl', 'parameters.ipv6.flowlabel' : 'flowlabel', 'parameters.nolearning' : 'nolearning', + 'parameters.vni_filter' : 'vnifilter', 'remote' : 'remote', 'source_address' : 'local', 'source_interface' : 'dev', @@ -138,10 +140,14 @@ class VXLANIf(Interface): if not isinstance(state, bool): raise ValueError('Value out of range') - cur_vlan_ids = [] if 'vlan_to_vni_removed' in self.config: - cur_vlan_ids = self.config['vlan_to_vni_removed'] - for vlan in cur_vlan_ids: + cur_vni_filter = get_vxlan_vni_filter(self.ifname) + for vlan, vlan_config in self.config['vlan_to_vni_removed'].items(): + # If VNI filtering is enabled, remove matching VNI filter + if dict_search('parameters.vni_filter', self.config) != None: + vni = vlan_config['vni'] + if vni in cur_vni_filter: + self._cmd(f'bridge vni delete dev {self.ifname} vni {vni}') self._cmd(f'bridge vlan del dev {self.ifname} vid {vlan}') # Determine current OS Kernel vlan_tunnel setting - only adjust when needed @@ -151,10 +157,9 @@ class VXLANIf(Interface): if cur_state != new_state: self.set_interface('vlan_tunnel', new_state) - # Determine current OS Kernel configured VLANs - os_configured_vlan_ids = get_vxlan_vlan_tunnels(self.ifname) - if 'vlan_to_vni' in self.config: + # Determine current OS Kernel configured VLANs + os_configured_vlan_ids = get_vxlan_vlan_tunnels(self.ifname) add_vlan = list_diff(list(self.config['vlan_to_vni'].keys()), os_configured_vlan_ids) for vlan, vlan_config in self.config['vlan_to_vni'].items(): @@ -168,6 +173,10 @@ class VXLANIf(Interface): self._cmd(f'bridge vlan add dev {self.ifname} vid {vlan}') self._cmd(f'bridge vlan add dev {self.ifname} vid {vlan} tunnel_info id {vni}') + # If VNI filtering is enabled, install matching VNI filter + if dict_search('parameters.vni_filter', self.config) != None: + self._cmd(f'bridge vni add dev {self.ifname} vni {vni}') + def update(self, config): """ General helper function which works on a dictionary retrived by get_config_dict(). It's main intention is to consolidate the scattered diff --git a/python/vyos/utils/network.py b/python/vyos/utils/network.py index 3b5e146e1..4f7021509 100644 --- a/python/vyos/utils/network.py +++ b/python/vyos/utils/network.py @@ -504,3 +504,36 @@ def get_vxlan_vlan_tunnels(interface: str) -> list: os_configured_vlan_ids.append(str(vlanStart)) return os_configured_vlan_ids + +def get_vxlan_vni_filter(interface: str) -> list: + """ Return a list of strings with VNIs configured in the Kernel""" + from json import loads + from vyos.utils.process import cmd + + if not interface.startswith('vxlan'): + raise ValueError('Only applicable for VXLAN interfaces!') + + # Determine current OS Kernel configured VNI filters in VXLAN interface + # + # $ bridge -j vni show dev vxlan1 + # [{"ifname":"vxlan1","vnis":[{"vni":100},{"vni":200},{"vni":300,"vniEnd":399}]}] + # + # Example output: ['10010', '10020', '10021', '10022'] + os_configured_vnis = [] + tmp = loads(cmd(f'bridge --json vni show dev {interface}')) + if tmp: + for tunnel in tmp[0].get('vnis', {}): + vniStart = tunnel['vni'] + if 'vniEnd' in tunnel: + vniEnd = tunnel['vniEnd'] + # Build a real list for user VNIs + vni_list = list(range(vniStart, vniEnd +1)) + # Convert list of integers to list or strings + os_configured_vnis.extend(map(str, vni_list)) + # Proceed with next tunnel - this one is complete + continue + + # Add single tunel id - not part of a range + os_configured_vnis.append(str(vniStart)) + + return os_configured_vnis |