summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/vyos/ifconfig/bridge.py28
-rw-r--r--python/vyos/ifconfig/macvlan.py29
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