summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/vyos/ifconfig/vpp/__init__.py24
-rw-r--r--python/vyos/ifconfig/vpp/bond.py152
-rw-r--r--python/vyos/ifconfig/vpp/interface.py56
-rw-r--r--python/vyos/vpp/interface/__init__.py2
-rw-r--r--python/vyos/vpp/interface/bond.py122
-rw-r--r--python/vyos/vpp/utils.py4
6 files changed, 234 insertions, 126 deletions
diff --git a/python/vyos/ifconfig/vpp/__init__.py b/python/vyos/ifconfig/vpp/__init__.py
new file mode 100644
index 000000000..117acb8d0
--- /dev/null
+++ b/python/vyos/ifconfig/vpp/__init__.py
@@ -0,0 +1,24 @@
+#
+# Copyright (C) VyOS Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+from .bond import VPPBondInterface
+from .interface import VPPInterface
+
+__all__ = [
+ 'VPPBondInterface',
+ 'VPPInterface',
+]
diff --git a/python/vyos/ifconfig/vpp/bond.py b/python/vyos/ifconfig/vpp/bond.py
new file mode 100644
index 000000000..75849a620
--- /dev/null
+++ b/python/vyos/ifconfig/vpp/bond.py
@@ -0,0 +1,152 @@
+#
+# Copyright (C) VyOS Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+from vyos.ifconfig import Interface
+from vyos.ifconfig.vpp.interface import VPPInterface
+
+
+class VPPBondInterface(Interface, VPPInterface):
+ def __init__(self, ifname, config):
+ self.ifname = ifname
+ self.instance = int(ifname.removeprefix('vppbond'))
+ self.vpp_ifname = f'BondEthernet{self.instance}'
+
+ # Initialize Interface (kernel) and VPP part
+ super().__init__(ifname)
+ VPPInterface.__init__(self, self.vpp_ifname)
+
+ self.index = self.vpp.get_sw_if_index(self.vpp_ifname)
+ self.state = 'up' if 'disable' not in config else 'down'
+ self.mode = config.get('mode')
+ self.load_balance = config.get('hash_policy')
+ self.mac = config.get('mac')
+
+ def _create(self):
+ pass
+
+ def add_bond(self):
+ """Create Bond interface
+ https://github.com/FDio/vpp/blob/stable/2306/src/vnet/bonding/bond.api
+ Example:
+ from vyos.ifconfig.vpp import VPPBondInterface
+ a = BondInterface(ifname='vppbond0', config)
+ a.add_bond()
+ """
+ # Create interface 'BondEthernetX'
+ create_args = {
+ 'id': self.instance,
+ 'mode': self.mode,
+ 'lb': self.load_balance,
+ }
+ if self.mac:
+ create_args.update({'use_custom_mac': True, 'mac_address': self.mac})
+ self.vpp.api.bond_create2(**create_args)
+ # Add LCP pair (kernel) interface
+ self.kernel_add()
+ # Set interface state
+ self.set_state(self.state)
+ self.set_admin_state(self.state)
+ self.index = self.vpp.get_sw_if_index(self.vpp_ifname)
+
+ def delete_bond(self):
+ """Delete Bond interface
+ Example:
+ from vyos.ifconfig.vpp import VPPBondInterface
+ a = VPPBondInterface(ifname='vppbond0', config)
+ a.delete_bond()
+ """
+ self.vpp.api.bond_delete(sw_if_index=self.index)
+
+ def add_member(self, interface):
+ """Add member to Bond interface
+ Example:
+ from vyos.ifconfig.vpp import VPPBondInterface
+ a = VPPBondInterface(ifname='vppbond0', config)
+ a.add_member(interface='eth0')
+ """
+ member_if_index = self.vpp.get_sw_if_index(interface)
+ self.vpp.api.bond_add_member(
+ bond_sw_if_index=self.index, sw_if_index=member_if_index
+ )
+ self.vpp.api.sw_interface_set_promisc(
+ sw_if_index=member_if_index, promisc_on=True
+ )
+
+ def detach_member(self, interface):
+ """Detach member from Bond interface
+ Example:
+ from vyos.ifconfig.vpp import VPPBondInterface
+ a = VPPBondInterface(ifname='vppbond0')
+ a.detach_member(interface='eth0')
+ """
+ member_if_index = self.vpp.get_sw_if_index(interface)
+ self.vpp.api.bond_detach_member(sw_if_index=member_if_index)
+
+ def get_members(self):
+ members = []
+ tmp = self.vpp.api.sw_member_interface_dump(sw_if_index=self.index)
+ for member in tmp:
+ members.append(member.interface_name)
+ return members
+
+ def kernel_add(self):
+ """Add LCP pair
+ Example:
+ from vyos.ifconfig.vpp import VPPBondInterface
+ a = VPPBondInterface(ifname='vppbond0')
+ a.kernel_add()
+ """
+ self.vpp.lcp_pair_add(self.vpp_ifname, self.ifname)
+
+ def kernel_delete(self):
+ """Delete LCP pair
+ Example:
+ from vyos.ifconfig.vpp import VPPBondInterface
+ a = VPPBondInterface(ifname='vppbond0')
+ a.kernel_delete()
+ """
+ self.vpp.lcp_pair_del(self.vpp_ifname, self.ifname)
+
+ def remove(self):
+ if self.index:
+ # Detach all existing members
+ members = self.get_members()
+ for member in members:
+ self.detach_member(interface=member)
+
+ # Delete lcp pair interface
+ if self.vpp.lcp_pair_find(vpp_name_hw=self.vpp_ifname):
+ self.kernel_delete()
+
+ # Delete bonding interface
+ self.delete_bond()
+
+ def update(self, config):
+ # Add bond interface
+ self.add_bond()
+
+ # Add members to bond
+ for member in config.get('member', {}).get('interface', []):
+ self.add_member(interface=member)
+
+ # Set rx-mode
+ rx_mode = config.get('vpp_settings', {}).get('interface_rx_mode')
+ if rx_mode:
+ self.set_rx_mode(rx_mode)
+
+ # Apply all settings to the lcp pair (kernel) interface
+ super().update(config)
diff --git a/python/vyos/ifconfig/vpp/interface.py b/python/vyos/ifconfig/vpp/interface.py
new file mode 100644
index 000000000..1b87af4d2
--- /dev/null
+++ b/python/vyos/ifconfig/vpp/interface.py
@@ -0,0 +1,56 @@
+#
+# Copyright (C) VyOS Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# 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 VPPInterface:
+ def __init__(self, vpp_ifname):
+ self.vpp_ifname = vpp_ifname
+ self.vpp = VPPControl()
+
+ def set_state(self, state: str):
+ """Set interface state to UP or DOWN
+ Args:
+ state (str): The state of the interface. Options are 'up' and 'down'.
+ Example:
+ from vyos.interface.vpp import VPPInterface
+ a = VPPInterface(vpp_ifname='eth0')
+ a.set_state(state='up')
+ """
+ if state not in ['up', 'down']:
+ raise ValueError(f"Invalid state: {state}")
+ state_flag = 1 if state == 'up' else 0
+ if_index = self.vpp.get_sw_if_index(self.vpp_ifname)
+ self.vpp.api.sw_interface_set_flags(sw_if_index=if_index, flags=state_flag)
+
+ def get_state(self):
+ """Get interface state
+ Example:
+ from vyos.interface.vpp import VPPInterface
+ a = VPPInterface(vpp_ifname='eth0')
+ a.get_state()
+ """
+ if_index = self.vpp.get_sw_if_index(self.vpp_ifname)
+ return self.vpp.api.sw_interface_dump(sw_if_index=if_index)[0]['flags']
+
+ def set_rx_mode(self, rx_mode):
+ lcp_pair = self.vpp.lcp_pair_find(vpp_name_hw=self.vpp_ifname)
+ if lcp_pair:
+ lcp_name = lcp_pair.get('vpp_name_kernel')
+ if lcp_name:
+ self.vpp.iface_rxmode(lcp_name, rx_mode)
diff --git a/python/vyos/vpp/interface/__init__.py b/python/vyos/vpp/interface/__init__.py
index 903b7cbfc..c54e5ca60 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 .bond import BondInterface
from .bridge import BridgeInterface
from .ethernet import EthernetInterface
from .geneve import GeneveInterface
@@ -28,7 +27,6 @@ from .wireguard import WireguardInterface
from .xconnect import XconnectInterface
__all__ = [
- 'BondInterface',
'BridgeInterface',
'EthernetInterface',
'GeneveInterface',
diff --git a/python/vyos/vpp/interface/bond.py b/python/vyos/vpp/interface/bond.py
deleted file mode 100644
index abfcf5d0d..000000000
--- a/python/vyos/vpp/interface/bond.py
+++ /dev/null
@@ -1,122 +0,0 @@
-#
-# Copyright (C) VyOS Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# 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.control_host import set_promisc
-from vyos.vpp.interface.interface import Interface
-
-
-class BondInterface(Interface):
- def __init__(
- self,
- ifname,
- mode: str = '',
- load_balance: int = 0,
- mac: str = '',
- kernel_interface: str = '',
- state: str = 'up',
- ):
- super().__init__(ifname)
- self.instance = int(ifname.removeprefix('bond'))
- self.ifname = f'BondEthernet{self.instance}'
- self.mode = mode
- self.load_balance = load_balance
- self.mac = mac
- self.kernel_interface = kernel_interface
- self.state = state
-
- def add(self):
- """Create Bond interface
- https://github.com/FDio/vpp/blob/stable/2306/src/vnet/bonding/bond.api
- Example:
- from vyos.vpp.interface import BondInterface
- a = BondInterface(ifname='bond0', mode=5)
- a.add()
- """
- # Create interface 'bondX'
- create_args = {
- 'id': self.instance,
- 'mode': self.mode,
- 'lb': self.load_balance,
- }
- if self.mac:
- create_args.update({'use_custom_mac': True, 'mac_address': self.mac})
- self.vpp.api.bond_create2(**create_args)
- if self.kernel_interface:
- self.vpp.lcp_pair_add(self.ifname, self.kernel_interface)
- # Set interface state
- self.set_state(self.state)
-
- def delete(self):
- """Delete Bond interface
- Example:
- from vyos.vpp.interface import BondInterface
- a = BondInterface(ifname='bond0')
- a.delete()
- """
- bond_if_index = self.vpp.get_sw_if_index(self.ifname)
- self.vpp.api.bond_delete(sw_if_index=bond_if_index)
-
- def add_member(self, interface):
- """Add member to Bond interface
- Example:
- from vyos.vpp.interface import BondInterface
- a = BondInterface(ifname='bond0')
- a.add_member(interface='eth0')
- """
- bond_if_index = self.vpp.get_sw_if_index(f'BondEthernet{self.instance}')
- member_if_index = self.vpp.get_sw_if_index(interface)
- member_if_type = self.vpp.get_sw_if_dev_type(interface)
- self.vpp.api.bond_add_member(
- bond_sw_if_index=bond_if_index, sw_if_index=member_if_index
- )
- self.vpp.api.sw_interface_set_promisc(
- sw_if_index=member_if_index, promisc_on=True
- )
- if member_if_type == 'AF_XDP interface':
- set_promisc(f'defunct_{interface}', 'on')
-
- def detach_member(self, interface):
- """Detach member from Bond interface
- Example:
- from vyos.vpp.interface import BondInterface
- a = BondInterface(ifname='bond0')
- a.detach_member(interface='eth0')
- """
- member_if_index = self.vpp.get_sw_if_index(interface)
- self.vpp.api.bond_detach_member(sw_if_index=member_if_index)
-
- def kernel_add(self):
- """Add LCP pair
- Example:
- from vyos.vpp.interface import BondInterface
- a = BondInterface(ifname='bond0', mode=5)
- a.kernel_add()
- """
- self.vpp.lcp_pair_add(self.ifname, self.kernel_interface)
-
- def kernel_delete(self):
- """Delete LCP pair
- Example:
- from vyos.vpp.interface import BondInterface
- a = BondInterface(ifname='bond0', mode=5)
- a.kernel_delete()
- """
- self.vpp.lcp_pair_del(self.ifname, self.kernel_interface)
-
- def lcp_pair_exists(self):
- """Check if LCP pair exists"""
- return bool(self.vpp.lcp_pair_find(self.kernel_interface))
diff --git a/python/vyos/vpp/utils.py b/python/vyos/vpp/utils.py
index 0c247e48a..5ae4cd296 100644
--- a/python/vyos/vpp/utils.py
+++ b/python/vyos/vpp/utils.py
@@ -58,9 +58,9 @@ def vpp_iface_name_transform(iface: str) -> str:
str: Interface name formatted as recognized by VPP (e.g., "BondEthernet0").
"""
vpp_iface_name = iface
- if vpp_iface_name.startswith('bond'):
+ if vpp_iface_name.startswith('vppbond'):
# interface name in VPP is BondEthernetX
- vpp_iface_name = vpp_iface_name.replace('bond', 'BondEthernet')
+ vpp_iface_name = vpp_iface_name.replace('vppbond', 'BondEthernet')
return vpp_iface_name