diff options
Diffstat (limited to 'python')
| -rw-r--r-- | python/vyos/ifconfig/bridge.py | 28 | ||||
| -rw-r--r-- | python/vyos/ifconfig/macvlan.py | 29 |
2 files changed, 35 insertions, 22 deletions
diff --git a/python/vyos/ifconfig/bridge.py b/python/vyos/ifconfig/bridge.py index f04d52546..448d743fe 100644 --- a/python/vyos/ifconfig/bridge.py +++ b/python/vyos/ifconfig/bridge.py @@ -113,8 +113,8 @@ class BridgeIf(Interface): 'del_port': { 'shellcmd': 'ip link set dev {value} nomaster', }, - 'add_local_fdb_entry': { - 'shellcmd': 'bridge fdb add {value} dev {ifname} self local', + 'replace_local_fdb_entry': { + 'shellcmd': 'bridge fdb replace {value} dev {ifname} self local', }, 'del_local_fdb_entry': { 'shellcmd': 'bridge fdb del {value} dev {ifname} self local', @@ -292,25 +292,33 @@ class BridgeIf(Interface): """ return self.get_interface('fdb_entries') - def add_local_fdb_entry(self, mac_address: str): + def replace_local_fdb_entry(self, mac_address: str, vlan=None): """ - Add a local FDB entry for the given MAC address on the bridge interface. + Add or replace a local FDB entry for the given MAC address on the bridge + interface, optionally bound to a VLAN. Example: >>> from vyos.ifconfig import BridgeIf - >>> BridgeIf('br0').add_local_fdb_entry('cc:38:2e:bf:7b:0d') + >>> BridgeIf('br0').replace_local_fdb_entry('cc:38:2e:bf:7b:0d', 100) """ - self.set_interface('add_local_fdb_entry', mac_address.lower()) + value = [mac_address.lower()] + if vlan: + value += ['vlan', str(vlan)] + self.set_interface('replace_local_fdb_entry', ' '.join(value)) - def del_local_fdb_entry(self, mac_address: str): + def del_local_fdb_entry(self, mac_address: str, vlan=None): """ - Remove a local FDB entry for the given MAC address on the bridge interface. + Remove a local FDB entry for the given MAC address on the bridge interface, + optionally bound to a VLAN. Example: >>> from vyos.ifconfig import BridgeIf - >>> BridgeIf('br0').del_local_fdb_entry('cc:38:2e:bf:7b:0d') + >>> BridgeIf('br0').del_local_fdb_entry('cc:38:2e:bf:7b:0d', 100) """ - self.set_interface('del_local_fdb_entry', mac_address.lower()) + value = [mac_address.lower()] + if vlan: + value += ['vlan', str(vlan)] + self.set_interface('del_local_fdb_entry', ' '.join(value)) def update(self, config): """ General helper function which works on a dictionary retrieved by diff --git a/python/vyos/ifconfig/macvlan.py b/python/vyos/ifconfig/macvlan.py index 0626b3d21..acf17f0ce 100644 --- a/python/vyos/ifconfig/macvlan.py +++ b/python/vyos/ifconfig/macvlan.py @@ -45,40 +45,45 @@ class MACVLANIf(Interface): # interface is always A/D down. It needs to be enabled explicitly self.set_admin_state('down') - def _get_bridge_by_source(self, source_interface: str) -> BridgeIf | None: + def _get_bridge_by_source(self, source_interface: str) -> tuple: """ - Resolve a source interface name to its root BridgeIf object. + Resolve a source interface name to its root BridgeIf object and the + bridge VLAN the anycast MAC belongs to. Handles plain bridge names (e.g. 'br0') and bridge sub-interfaces - with one or two VLAN suffixes (e.g. 'br0.100', 'br0.100.200'). + with one or two VLAN suffixes (e.g. 'br0.100', 'br0.100.200'). The + first suffix is the bridge VLAN. It is only returned for VLAN-aware + bridges, the kernel rejects VLAN FDB entries on any other bridge. + + Returns (bridge, vlan), bridge is None if it does not exist. """ - bridge = None + bridge = vlan = None if source_interface.startswith('br'): - # We only need the root bridge name, so unpack with *_ to - # discard the VLAN parts. - bridge_ifname, *_ = split_interface_vlans(source_interface) + bridge_ifname, vlan, _ = split_interface_vlans(source_interface) if interface_exists(bridge_ifname): bridge = BridgeIf(bridge_ifname) + if not int(bridge.get_vlan_filter()): + vlan = None - return bridge + return bridge, vlan def _create_anycast_gateway(self, source_interface, mac): """Install a local FDB entry on the parent bridge for the anycast MAC""" if source_interface and mac: - bridge = self._get_bridge_by_source(source_interface) + bridge, vlan = self._get_bridge_by_source(source_interface) if bridge: - bridge.add_local_fdb_entry(mac) + bridge.replace_local_fdb_entry(mac, vlan) def _delete_anycast_gateway(self, source_interface, mac): """Remove the local FDB entry from the parent bridge for the anycast MAC""" if source_interface and mac: - bridge = self._get_bridge_by_source(source_interface) + bridge, vlan = self._get_bridge_by_source(source_interface) if bridge: try: - bridge.del_local_fdb_entry(mac) + bridge.del_local_fdb_entry(mac, vlan) except OSError: pass # Bridge may already be gone, that is fine |
