summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorChristian Breunig <christian@breunig.cc>2026-03-04 09:22:25 +0100
committerGitHub <noreply@github.com>2026-03-04 09:22:25 +0100
commit3030e33b26c1a895179747f2444a0cd79d59f891 (patch)
tree86166dcd8b9ddf17611a0b6f2142d1130604e981 /python
parentd47be4a8e2119e2be0be5fe9d7c29d7d8eaf24d9 (diff)
parentc90512f68dbabe6f005c259f6e787abe527fe975 (diff)
downloadvyos-1x-3030e33b26c1a895179747f2444a0cd79d59f891.tar.gz
vyos-1x-3030e33b26c1a895179747f2444a0cd79d59f891.zip
Merge pull request #5022 from natali-rs1985/T8327
vpp: T8327: Migrate bridge interface to 'interfaces vpp bridge'
Diffstat (limited to 'python')
-rw-r--r--python/vyos/ifconfig/vpp/__init__.py2
-rw-r--r--python/vyos/ifconfig/vpp/bridge.py (renamed from python/vyos/vpp/interface/bridge.py)122
-rw-r--r--python/vyos/vpp/config_deps.py4
-rw-r--r--python/vyos/vpp/config_verify.py11
-rw-r--r--python/vyos/vpp/interface/__init__.py2
5 files changed, 81 insertions, 60 deletions
diff --git a/python/vyos/ifconfig/vpp/__init__.py b/python/vyos/ifconfig/vpp/__init__.py
index 7abe402c6..38f72e42f 100644
--- a/python/vyos/ifconfig/vpp/__init__.py
+++ b/python/vyos/ifconfig/vpp/__init__.py
@@ -16,6 +16,7 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
from .bond import VPPBondInterface
+from .bridge import VPPBridgeInterface
from .gre import VPPGREInterface
from .interface import VPPInterface
from .ipip import VPPIPIPInterface
@@ -24,6 +25,7 @@ from .vxlan import VPPVXLANInterface
__all__ = [
'VPPBondInterface',
+ 'VPPBridgeInterface',
'VPPGREInterface',
'VPPInterface',
'VPPIPIPInterface',
diff --git a/python/vyos/vpp/interface/bridge.py b/python/vyos/ifconfig/vpp/bridge.py
index 1d1a6e1b4..fce0dbfbb 100644
--- a/python/vyos/vpp/interface/bridge.py
+++ b/python/vyos/ifconfig/vpp/bridge.py
@@ -15,27 +15,16 @@
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-from vyos.vpp import VPPControl
-
-
-class BridgeInterface:
- def __init__(
- self,
- ifname: str,
- flood: bool = True,
- forward: bool = True,
- learn: bool = True,
- uu_flood: bool = True,
- arp_term: bool = False,
- ):
- self.ifname = ifname
- self.interface_suffix = int(self.ifname.replace('br', ''))
- self.flood = flood
- self.forward = forward
- self.learn = learn
- self.uu_flood = uu_flood
- self.arp_term = arp_term
- self.vpp = VPPControl()
+from vyos.ifconfig.vpp.interface import VPPInterface
+from vyos.vpp.utils import iftunnel_transform
+
+
+class VPPBridgeInterface(VPPInterface):
+ def __init__(self, ifname):
+ self.instance = int(ifname.removeprefix('vppbr'))
+ self.vpp_ifname = f'br{self.instance}'
+
+ super().__init__(self.vpp_ifname)
def add(self):
"""Create Bridge interface
@@ -44,18 +33,18 @@ class BridgeInterface:
Bridge-domain 0 is reserved for the default bridge-domain.
Example:
- from vyos.vpp.interface import BridgeInterface
- a = BridgeInterface(ifname='br23')
+ from vyos.ifconfig.vpp import VPPBridgeInterface
+ a = VPPBridgeInterface(ifname='br23')
a.add()
"""
self.vpp.api.bridge_domain_add_del_v2(
is_add=True,
- bd_id=self.interface_suffix,
- flood=self.flood,
- forward=self.forward,
- learn=self.learn,
- uu_flood=self.uu_flood,
- arp_term=self.arp_term,
+ bd_id=self.instance,
+ flood=True,
+ forward=True,
+ learn=True,
+ uu_flood=True,
+ arp_term=False,
)
def delete(self):
@@ -64,11 +53,18 @@ class BridgeInterface:
Bridge-members must be detached before deleting the bridge interface.
Example:
- from vyos.vpp.interface import BridgeInterface
- a = BridgeInterface(ifname='br23')
+ from vyos.ifconfig.vpp import VPPBridgeInterface
+ a = VPPBridgeInterface(ifname='br23')
a.delete()
"""
- self.vpp.api.bridge_domain_add_del_v2(is_add=False, bd_id=self.interface_suffix)
+ self.vpp.api.bridge_domain_add_del_v2(is_add=False, bd_id=self.instance)
+
+ def get_members(self):
+ bridge = self.vpp.api.bridge_domain_dump(bd_id=self.instance)[0]
+ members = []
+ for member in bridge.sw_if_details:
+ members.append(member.sw_if_index)
+ return members
def add_member(self, member: str | int, port_type: int = 0):
"""Add member to Bridge interface
@@ -83,24 +79,16 @@ class BridgeInterface:
port_type: 0 - Normal port, 1 - BVI port
Example:
- from vyos.vpp.interface import BridgeInterface
- a = BridgeInterface(ifname='br23')
+ from vyos.ifconfig.vpp import VPPBridgeInterface
+ a = VPPBridgeInterface(ifname='br23')
a.add_member(member='eth0')
"""
- bridge_index = self.interface_suffix
- # If the 'member' is an Integer or digit, assume it's an interface index
- if isinstance(member, int):
- member_if_index = member
- elif member.isdigit():
- member_if_index = int(member)
- else:
- member_if_index = self.vpp.get_sw_if_index(member)
-
+ member_if_index = self.vpp.get_sw_if_index(member)
return self.vpp.api.sw_interface_set_l2_bridge(
- rx_sw_if_index=member_if_index, bd_id=bridge_index, port_type=port_type
+ rx_sw_if_index=member_if_index, bd_id=self.instance, port_type=port_type
)
- def detach_member(self, member: str | int):
+ def detach_member(self, member: int):
"""Detach member from Bridge interface.
Bridge-domain 0 is reserved for the default bridge-domain.
The `member` parameter can be either the name (str) or the index (int)
@@ -111,19 +99,41 @@ class BridgeInterface:
to be detached from the bridge.
Example:
- from vyos.vpp.interface import BridgeInterface
- a = BridgeInterface(ifname='br23')
+ from vyos.ifconfig.vpp import VPPBridgeInterface
+ a = VPPBridgeInterface(ifname='br23')
a.detach_member(member='eth0')
"""
- # If the 'member' is an Integer or digit, assume it's an interface index
- if isinstance(member, int):
- member_if_index = member
- elif member.isdigit():
- member_if_index = int(member)
- else:
- member_if_index = self.vpp.get_sw_if_index(member)
-
# enable=0, 0 = Enable L3 mode
return self.vpp.api.sw_interface_set_l2_bridge(
- rx_sw_if_index=member_if_index, bd_id=0, port_type=0, enable=0
+ rx_sw_if_index=member, bd_id=0, port_type=0, enable=0
)
+
+ def remove(self):
+ if self.vpp.api.bridge_domain_dump(bd_id=self.instance):
+ # Detach all existing members
+ members = self.get_members()
+ for member in members:
+ self.detach_member(member=member)
+
+ # Delete bridge interface
+ self.delete()
+
+ def update(self, config):
+ # Add bridge interface
+ self.add()
+
+ # Add members to bridge
+ for member, member_config in (
+ config.get('member', {}).get('interface', []).items()
+ ):
+ member = member.removeprefix('vpp')
+ if member.startswith('vxlan'):
+ member = iftunnel_transform(member)
+ elif member.startswith('lo'):
+ # interface name in VPP is loopX
+ member = member.replace('lo', 'loop')
+ elif member.startswith('bond'):
+ # interface name in VPP is BondEthernetX
+ member = member.replace('bond', 'BondEthernet')
+ port = 1 if 'bvi' in member_config else 0
+ self.add_member(member=member, port_type=port)
diff --git a/python/vyos/vpp/config_deps.py b/python/vyos/vpp/config_deps.py
index dffd865d1..4aab90a4a 100644
--- a/python/vyos/vpp/config_deps.py
+++ b/python/vyos/vpp/config_deps.py
@@ -61,7 +61,7 @@ def deps_bridge_dict(conf) -> dict[str, list[str]]:
"""
bridge_members_dict: dict[str, list[str]] = {}
config = conf.get_config_dict(
- ['vpp', 'interfaces', 'bridge'],
+ ['interfaces', 'vpp', 'bridge'],
key_mangling=('-', '_'),
get_first_key=True,
no_tag_node_value_mangle=True,
@@ -69,7 +69,7 @@ def deps_bridge_dict(conf) -> dict[str, list[str]]:
for bridge_name, bridge_config in config.items():
for member_name in bridge_config.get('member', {}).get('interface', []):
- bridge_ifaces_list = bridge_members_dict.get(bridge_name, [])
+ bridge_ifaces_list = bridge_members_dict.get(member_name, [])
bridge_ifaces_list.append(bridge_name)
bridge_members_dict.update({member_name: bridge_ifaces_list})
diff --git a/python/vyos/vpp/config_verify.py b/python/vyos/vpp/config_verify.py
index 84c32f1e6..dab22cf8f 100644
--- a/python/vyos/vpp/config_verify.py
+++ b/python/vyos/vpp/config_verify.py
@@ -108,6 +108,17 @@ def verify_vpp_remove_xconnect_interface(config: dict):
)
+def verify_vpp_remove_bridge_interface(config: dict):
+ if not 'deleted' in config:
+ return
+ for bridge_member, bridge_iface in config.get('bridge_members').items():
+ if bridge_member == config.get('ifname'):
+ raise ConfigError(
+ f'interface "{bridge_member}" is still in use within "interfaces vpp bridge". '
+ f'Please remove it from "interface vpp bridge {bridge_iface}" before proceeding.'
+ )
+
+
def verify_vpp_tunnel_source_address(config: dict):
from vyos.utils.network import is_intf_addr_assigned
diff --git a/python/vyos/vpp/interface/__init__.py b/python/vyos/vpp/interface/__init__.py
index cdfb0c0b8..0a3176199 100644
--- a/python/vyos/vpp/interface/__init__.py
+++ b/python/vyos/vpp/interface/__init__.py
@@ -15,7 +15,6 @@
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-from .bridge import BridgeInterface
from .ethernet import EthernetInterface
from .geneve import GeneveInterface
from .interface import Interface
@@ -23,7 +22,6 @@ from .wireguard import WireguardInterface
from .xconnect import XconnectInterface
__all__ = [
- 'BridgeInterface',
'EthernetInterface',
'GeneveInterface',
'Interface',