diff options
| author | Nataliia Solomko <natalirs1985@gmail.com> | 2026-02-26 15:27:27 +0200 |
|---|---|---|
| committer | Nataliia Solomko <natalirs1985@gmail.com> | 2026-02-27 21:26:00 +0200 |
| commit | 3755dfa7612ffa7edc94537220340a00c9db13ad (patch) | |
| tree | 5ab1f39a140deec9c2c3f98e502b7551848b8125 /python | |
| parent | bfb8537c4e79e18e960cf15064658d3ee50fd05a (diff) | |
| download | vyos-1x-3755dfa7612ffa7edc94537220340a00c9db13ad.tar.gz vyos-1x-3755dfa7612ffa7edc94537220340a00c9db13ad.zip | |
vpp: T8296: Move vxlan interface from vpp section to 'interfaces vpp vxlan'
Diffstat (limited to 'python')
| -rw-r--r-- | python/vyos/ifconfig/vpp/__init__.py | 2 | ||||
| -rw-r--r-- | python/vyos/ifconfig/vpp/vxlan.py | 125 | ||||
| -rw-r--r-- | python/vyos/vpp/config_verify.py | 2 | ||||
| -rw-r--r-- | python/vyos/vpp/interface/__init__.py | 2 | ||||
| -rw-r--r-- | python/vyos/vpp/interface/vxlan.py | 106 | ||||
| -rw-r--r-- | python/vyos/vpp/interface/xconnect.py | 8 | ||||
| -rw-r--r-- | python/vyos/vpp/utils.py | 18 |
7 files changed, 149 insertions, 114 deletions
diff --git a/python/vyos/ifconfig/vpp/__init__.py b/python/vyos/ifconfig/vpp/__init__.py index 117acb8d0..bda2f76c8 100644 --- a/python/vyos/ifconfig/vpp/__init__.py +++ b/python/vyos/ifconfig/vpp/__init__.py @@ -17,8 +17,10 @@ from .bond import VPPBondInterface from .interface import VPPInterface +from .vxlan import VPPVXLANInterface __all__ = [ 'VPPBondInterface', 'VPPInterface', + 'VPPVXLANInterface', ] diff --git a/python/vyos/ifconfig/vpp/vxlan.py b/python/vyos/ifconfig/vpp/vxlan.py new file mode 100644 index 000000000..8ca9bee70 --- /dev/null +++ b/python/vyos/ifconfig/vpp/vxlan.py @@ -0,0 +1,125 @@ +# VyOS implementation of VPP VXLAN interface +# +# 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 VPPVXLANInterface(Interface, VPPInterface): + """Interface VXLAN""" + + def __init__(self, ifname, config): + self.ifname = ifname + self.instance = int(ifname.removeprefix('vppvxlan')) + self.vpp_ifname = f'vxlan_tunnel{self.instance}' + + super().__init__(ifname) + VPPInterface.__init__(self, self.vpp_ifname) + + self.index = self.vpp.get_sw_if_index(self.vpp_ifname) + self.src_address = config.get('source_address') + self.dst_address = config.get('remote') + self.vni = int(config.get('vni', 0)) + self.state = 'up' if 'disable' not in config else 'down' + + def _create(self): + pass + + def get_vxlan(self): + tunnels = self.vpp.api.vxlan_tunnel_dump(sw_if_index=self.index) + return tunnels[0] if tunnels else None + + def add_vxlan(self): + """Create VXLAN interface + https://github.com/FDio/vpp/blob/stable/2306/src/plugins/vxlan/vxlan.api + + Example: + from vyos.ifconfig.vpp import VPPVXLANInterface + a = VPPVXLANInterface(ifname='vppvxlan23', config) + a.add_vxlan() + """ + self.vpp.api.vxlan_add_del_tunnel_v3( + is_add=True, + src_address=self.src_address, + dst_address=self.dst_address, + vni=self.vni, + instance=self.instance, + decap_next_index=1, + is_l3=False, + ) + # 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_vxlan(self): + """Delete VXLAN interface + Example: + from vyos.ifconfig.vpp import VPPVXLANInterface + a = VPPVXLANInterface(ifname='vppvxlan23', config) + a.delete_vxlan() + """ + vxlan = self.get_vxlan() + if vxlan: + return self.vpp.api.vxlan_add_del_tunnel_v3( + is_add=False, + src_address=vxlan.src_address, + dst_address=vxlan.dst_address, + vni=vxlan.vni, + is_l3=False, + ) + + def kernel_add(self): + """Add LCP pair + Example: + from vyos.ifconfig.vpp import VPPVXLANInterface + a = VPPVXLANInterface(ifname='vppvxlan23', config) + 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 VPPVXLANInterface + a = VPPVXLANInterface(ifname='vppvxlan23', config) + a.kernel_delete() + """ + self.vpp.lcp_pair_del(self.vpp_ifname, self.ifname) + + def remove(self): + if self.index: + # Delete lcp pair interface + if self.vpp.lcp_pair_find(vpp_name_hw=self.vpp_ifname): + self.kernel_delete() + + # Delete vxlan interface + self.delete_vxlan() + + def update(self, config): + # Add vxlan interface + self.add_vxlan() + + # Set rx-mode + rx_mode = config.get('vpp_settings', {}).get('interface_rx_mode') + if rx_mode: + self.set_rx_mode(rx_mode) + + super().update(config) diff --git a/python/vyos/vpp/config_verify.py b/python/vyos/vpp/config_verify.py index 1e56457da..84c32f1e6 100644 --- a/python/vyos/vpp/config_verify.py +++ b/python/vyos/vpp/config_verify.py @@ -98,7 +98,7 @@ def verify_vpp_exists_kernel_interface(config: dict): def verify_vpp_remove_xconnect_interface(config: dict): - if not config.get('remove'): + if not 'deleted' in config: return for xconn_member, xconn_iface in config.get('xconn_members').items(): if xconn_member == config.get('ifname'): diff --git a/python/vyos/vpp/interface/__init__.py b/python/vyos/vpp/interface/__init__.py index c54e5ca60..f17a12d43 100644 --- a/python/vyos/vpp/interface/__init__.py +++ b/python/vyos/vpp/interface/__init__.py @@ -22,7 +22,6 @@ from .gre import GREInterface from .interface import Interface from .ipip import IPIPInterface from .loopback import LoopbackInterface -from .vxlan import VXLANInterface from .wireguard import WireguardInterface from .xconnect import XconnectInterface @@ -34,7 +33,6 @@ __all__ = [ 'Interface', 'IPIPInterface', 'LoopbackInterface', - 'VXLANInterface', 'WireguardInterface', 'XconnectInterface', ] diff --git a/python/vyos/vpp/interface/vxlan.py b/python/vyos/vpp/interface/vxlan.py deleted file mode 100644 index 4be5b5ec9..000000000 --- a/python/vyos/vpp/interface/vxlan.py +++ /dev/null @@ -1,106 +0,0 @@ -# VyOS implementation of VPP VXLAN interface -# -# 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 -from vyos.vpp.interface.interface import Interface - - -def show(): - """Show VXLAN interface - Example: - from vyos.vpp.interface import vxlan - vxlan.show() - """ - vpp = VPPControl() - return vpp.api.vxlan_tunnel_dump() - - -class VXLANInterface(Interface): - """Interface VXLAN""" - - def __init__( - self, - ifname, - source_address, - remote, - vni, - kernel_interface: str = '', - state: str = 'up', - ): - super().__init__(ifname) - self.instance = int(ifname.removeprefix('vxlan')) - self.ifname = f'vxlan_tunnel{self.instance}' - self.src_address = source_address - self.dst_address = remote - self.vni = vni - self.kernel_interface = kernel_interface - self.initial_state = state - - def add(self): - """Create VXLAN interface - https://github.com/FDio/vpp/blob/stable/2306/src/plugins/vxlan/vxlan.api - - Example: - from vyos.vpp.interface import VXLANInterface - a = VXLANInterface(ifname='vxlan23', source_address='192.0.2.1', remote='203.0.113.23', vni=23) - a.add() - """ - self.vpp.api.vxlan_add_del_tunnel_v3( - is_add=True, - src_address=self.src_address, - dst_address=self.dst_address, - vni=self.vni, - instance=self.instance, - decap_next_index=1, - is_l3=False, - ) - # Set interface state - self.set_state(self.initial_state) - - def delete(self): - """Delete VXLAN interface - Example: - from vyos.vpp.interface import VXLANInterface - a = VXLANInterface(ifname='vxlan23', source_address='192.0.2.1', remote='203.0.113.23', vni=23) - a.delete() - """ - return self.vpp.api.vxlan_add_del_tunnel_v3( - is_add=False, - src_address=self.src_address, - dst_address=self.dst_address, - vni=self.vni, - is_l3=False, - ) - - def kernel_add(self): - """Add LCP pair - Example: - from vyos.vpp.interface import VXLANInterface - a = VXLANInterface(ifname='vxlan23', source_address='192.0.2.1', remote='203.0.113.23', vni=23, kernel_interface='vpptap10') - 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 VXLANInterface - a = VXLANInterface(ifname='vxlan23', source_address='192.0.2.1', remote='203.0.113.23', vni=23) - a.kernel_delete() - """ - self.vpp.lcp_pair_del(self.ifname, self.kernel_interface) diff --git a/python/vyos/vpp/interface/xconnect.py b/python/vyos/vpp/interface/xconnect.py index 299a61405..603f7f90b 100644 --- a/python/vyos/vpp/interface/xconnect.py +++ b/python/vyos/vpp/interface/xconnect.py @@ -42,8 +42,8 @@ class XconnectInterface: a.add_l2_xconnect() """ interface_transform_filter = ('vxlan', 'gre') - first_member = self.members[0] - second_member = self.members[1] + first_member = self.members[0].removeprefix('vpp') + second_member = self.members[1].removeprefix('vpp') # Check if member in required filter to transform 'vxlanX' => 'vxlan_tunnelX' if first_member.startswith(interface_transform_filter): first_member = iftunnel_transform(first_member) @@ -73,8 +73,8 @@ class XconnectInterface: a.del_l2_xconnect() """ interface_transform_filter = ('vxlan', 'gre') - first_member = self.members[0] - second_member = self.members[1] + first_member = self.members[0].removeprefix('vpp') + second_member = self.members[1].removeprefix('vpp') # Check if member in required filter to transform 'vxlanX' => 'vxlan_tunnelX' if first_member.startswith(interface_transform_filter): first_member = iftunnel_transform(first_member) diff --git a/python/vyos/vpp/utils.py b/python/vyos/vpp/utils.py index 5ae4cd296..5976b2189 100644 --- a/python/vyos/vpp/utils.py +++ b/python/vyos/vpp/utils.py @@ -27,7 +27,7 @@ mem_shift = {'K': 10, 'KB': 10, 'M': 20, 'MB': 20, 'G': 30, 'GB': 30} def iftunnel_transform(iface: str) -> str: - """Transform interface name from `xxxNN` to `xxx_tunnelNN` + """Transform interface name from `vppxxxNN` to `xxx_tunnelNN` Args: iface (str): original interface name @@ -38,6 +38,8 @@ def iftunnel_transform(iface: str) -> str: Returns: str: Transformed interface name """ + # Remove vpp prefix + iface = iface.removeprefix('vpp') # Check format if not iface[0].isascii() or not iface[-1].isdecimal(): raise ValueError(f'Wrong interface name format: {iface}') @@ -87,6 +89,15 @@ def cli_ifaces_list(config_instance, mode: str = 'candidate') -> list[str]: with_recursive_defaults=True, ) + interfaces_config = config_instance.get_config_dict( + ['interfaces', 'vpp'], + key_mangling=('-', '_'), + effective=effective_mode, + get_first_key=True, + no_tag_node_value_mangle=True, + with_recursive_defaults=True, + ) + vpp_ifaces: list[str] = [] # Get a list of Ethernet interfaces @@ -98,6 +109,11 @@ def cli_ifaces_list(config_instance, mode: str = 'candidate') -> list[str]: for iface in config.get('interfaces', {}).get(iface_type, {}).keys(): vpp_ifaces.append(iface) + # Get a list of interfaces VPP + for iface_type in interfaces_config.keys(): + for iface in interfaces_config.get(iface_type, {}).keys(): + vpp_ifaces.append(iface) + return vpp_ifaces |
