summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Breunig <christian@breunig.cc>2026-03-03 13:28:20 +0100
committerGitHub <noreply@github.com>2026-03-03 13:28:20 +0100
commitd47be4a8e2119e2be0be5fe9d7c29d7d8eaf24d9 (patch)
tree9101e996fd134a83cb2708e104bcdd7a85caa197
parent00361b88005948802344adbe6184057cee91cde4 (diff)
parent99f617c88e57453315ee97cba88d3de1a24a5f01 (diff)
downloadvyos-1x-d47be4a8e2119e2be0be5fe9d7c29d7d8eaf24d9.tar.gz
vyos-1x-d47be4a8e2119e2be0be5fe9d7c29d7d8eaf24d9.zip
Merge pull request #5020 from natali-rs1985/T8325
vpp: T8325: Migrate gre interface to 'interfaces vpp gre'
-rw-r--r--interface-definitions/vpp.xml.in67
-rw-r--r--interface-definitions/vpp_interface_gre.xml.in81
-rw-r--r--python/vyos/ifconfig/vpp/__init__.py2
-rw-r--r--python/vyos/ifconfig/vpp/gre.py138
-rw-r--r--python/vyos/vpp/interface/__init__.py2
-rw-r--r--python/vyos/vpp/interface/gre.py140
-rw-r--r--python/vyos/vpp/interface/xconnect.py4
-rw-r--r--smoketest/configs/assert/vpp22
-rwxr-xr-xsmoketest/scripts/cli/test_vpp.py77
-rwxr-xr-xsrc/conf_mode/vpp.py33
-rw-r--r--src/conf_mode/vpp_interfaces_bridge.py2
-rw-r--r--src/conf_mode/vpp_interfaces_gre.py159
-rw-r--r--src/migration-scripts/vpp/5-to-634
13 files changed, 342 insertions, 419 deletions
diff --git a/interface-definitions/vpp.xml.in b/interface-definitions/vpp.xml.in
index 733e8eb83..517129e78 100644
--- a/interface-definitions/vpp.xml.in
+++ b/interface-definitions/vpp.xml.in
@@ -79,73 +79,6 @@
<!-- #include <include/kernel-interface-tun.xml.i> -->
<!-- </children> -->
<!-- </tagNode> -->
- <tagNode name="gre" owner="${vyos_conf_scripts_dir}/vpp_interfaces_gre.py">
- <properties>
- <priority>325</priority>
- <help>Generic Network Encapsulation (GRE) Interface</help>
- <constraint>
- <regex>gre[0-9]+</regex>
- </constraint>
- <constraintErrorMessage>GRE interface must be named greN</constraintErrorMessage>
- <valueHelp>
- <format>greN</format>
- <description>GRE interface name</description>
- </valueHelp>
- </properties>
- <children>
- #include <include/generic-description.xml.i>
- #include <include/interface/disable.xml.i>
- <leafNode name="mode">
- <properties>
- <help>GRE tunnel mode</help>
- <completionHelp>
- <list>point-to-point point-to-multipoint</list>
- </completionHelp>
- <valueHelp>
- <format>point-to-point</format>
- <description>Point to point mode</description>
- </valueHelp>
- <valueHelp>
- <format>point-to-multipoint</format>
- <description>Point to multipoint mode</description>
- </valueHelp>
- <constraint>
- <regex>(point-to-point|point-to-multipoint)</regex>
- </constraint>
- <constraintErrorMessage>Invalid mode, must be one of: point-to-point or point-to-multipoint</constraintErrorMessage>
- </properties>
- <defaultValue>point-to-point</defaultValue>
- </leafNode>
- <leafNode name="tunnel-type">
- <properties>
- <help>GRE tunnel type</help>
- <completionHelp>
- <list>erspan l3 teb</list>
- </completionHelp>
- <valueHelp>
- <format>erspan</format>
- <description>Encapsulated Remote Switched Port Analyzer</description>
- </valueHelp>
- <valueHelp>
- <format>l3</format>
- <description>Generic Routing Encapsulation (network layer)</description>
- </valueHelp>
- <valueHelp>
- <format>teb</format>
- <description>L2 Transparent Ethernet Bridge</description>
- </valueHelp>
- <constraint>
- <regex>(erspan|l3|teb)</regex>
- </constraint>
- <constraintErrorMessage>Invalid encapsulation, must be one of: l3, teb or erspan</constraintErrorMessage>
- </properties>
- <defaultValue>l3</defaultValue>
- </leafNode>
- #include <include/source-address-ipv4-ipv6.xml.i>
- #include <include/interface/tunnel-remote.xml.i>
- #include <include/kernel-interface-tun.xml.i>
- </children>
- </tagNode>
<tagNode name="xconnect" owner="${vyos_conf_scripts_dir}/vpp_interfaces_xconnect.py">
<properties>
<help>Layer 2 cross connect</help>
diff --git a/interface-definitions/vpp_interface_gre.xml.in b/interface-definitions/vpp_interface_gre.xml.in
new file mode 100644
index 000000000..7636c6e2f
--- /dev/null
+++ b/interface-definitions/vpp_interface_gre.xml.in
@@ -0,0 +1,81 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+ <node name='interfaces'>
+ <children>
+ <node name='vpp'>
+ <children>
+ <tagNode name="gre" owner="${vyos_conf_scripts_dir}/vpp_interfaces_gre.py">
+ <properties>
+ <priority>325</priority>
+ <help>Generic Network Encapsulation (GRE) Interface</help>
+ <constraint>
+ <regex>vppgre[0-9]+</regex>
+ </constraint>
+ <constraintErrorMessage>GRE interface must be named vppgreN</constraintErrorMessage>
+ <valueHelp>
+ <format>vppgreN</format>
+ <description>GRE interface name</description>
+ </valueHelp>
+ </properties>
+ <children>
+ #include <include/generic-description.xml.i>
+ #include <include/interface/disable.xml.i>
+ <!-- Disable as point-to-multipoint mode does not work without 'teib' feature that is not implemented yet -->
+ <!-- <leafNode name="mode">
+ <leafNode name="mode">
+ <properties>
+ <help>GRE tunnel mode</help>
+ <completionHelp>
+ <list>point-to-point point-to-multipoint</list>
+ </completionHelp>
+ <valueHelp>
+ <format>point-to-point</format>
+ <description>Point to point mode</description>
+ </valueHelp>
+ <valueHelp>
+ <format>point-to-multipoint</format>
+ <description>Point to multipoint mode</description>
+ </valueHelp>
+ <constraint>
+ <regex>(point-to-point|point-to-multipoint)</regex>
+ </constraint>
+ <constraintErrorMessage>Invalid mode, must be one of: point-to-point or point-to-multipoint</constraintErrorMessage>
+ </properties>
+ <defaultValue>point-to-point</defaultValue>
+ </leafNode> -->
+ <leafNode name="tunnel-type">
+ <properties>
+ <help>GRE tunnel type</help>
+ <completionHelp>
+ <list>erspan l3 teb</list>
+ </completionHelp>
+ <valueHelp>
+ <format>erspan</format>
+ <description>Encapsulated Remote Switched Port Analyzer</description>
+ </valueHelp>
+ <valueHelp>
+ <format>l3</format>
+ <description>Generic Routing Encapsulation (network layer)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>teb</format>
+ <description>L2 Transparent Ethernet Bridge</description>
+ </valueHelp>
+ <constraint>
+ <regex>(erspan|l3|teb)</regex>
+ </constraint>
+ <constraintErrorMessage>Invalid encapsulation, must be one of: l3, teb or erspan</constraintErrorMessage>
+ </properties>
+ <defaultValue>l3</defaultValue>
+ </leafNode>
+ #include <include/source-address-ipv4-ipv6.xml.i>
+ #include <include/interface/tunnel-remote.xml.i>
+ #include <include/interface/address-ipv4-ipv6.xml.i>
+ #include <include/interface/mtu-68-16000.xml.i>
+ </children>
+ </tagNode>
+ </children>
+ </node>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/python/vyos/ifconfig/vpp/__init__.py b/python/vyos/ifconfig/vpp/__init__.py
index b0a477c28..7abe402c6 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 .gre import VPPGREInterface
from .interface import VPPInterface
from .ipip import VPPIPIPInterface
from .loopback import VPPLoopbackInterface
@@ -23,6 +24,7 @@ from .vxlan import VPPVXLANInterface
__all__ = [
'VPPBondInterface',
+ 'VPPGREInterface',
'VPPInterface',
'VPPIPIPInterface',
'VPPLoopbackInterface',
diff --git a/python/vyos/ifconfig/vpp/gre.py b/python/vyos/ifconfig/vpp/gre.py
new file mode 100644
index 000000000..7ab600998
--- /dev/null
+++ b/python/vyos/ifconfig/vpp/gre.py
@@ -0,0 +1,138 @@
+# VyOS implementation of VPP GRE 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 VPPGREInterface(Interface, VPPInterface):
+ """
+ Class representing a GRE (Generic Routing Encapsulation) interface.
+ """
+
+ # Mapping of tunnel types https://github.com/FDio/vpp/blob/stable/2406/src/plugins/gre/gre.api#L25-L35
+ TUNNEL_TYPE_MAP = {
+ 'l3': 0,
+ 'teb': 1,
+ 'erspan': 2,
+ }
+
+ MODE_MAP = {
+ 'point-to-point': 0,
+ # 'point-to-multipoint': 1,
+ }
+
+ def __init__(self, ifname, config):
+ self.ifname = ifname
+ self.instance = int(ifname.removeprefix('vppgre'))
+ self.vpp_ifname = f'gre{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.src_address = config.get('source_address')
+ self.dst_address = config.get('remote')
+ self.tunnel_type = self.TUNNEL_TYPE_MAP.get(config.get('tunnel_type'), 0)
+ self.mode = self.MODE_MAP['point-to-point']
+
+ def _create(self):
+ pass
+
+ def get_gre(self):
+ tunnels = self.vpp.api.gre_tunnel_dump(sw_if_index=self.index)
+ return tunnels if tunnels else None
+
+ def add_gre(self):
+ """Create GRE interface
+ https://github.com/FDio/vpp/blob/stable/2406/src/plugins/gre/gre.api
+ Example:
+ from vyos.ifconfig.vpp import VPPGREInterface
+ a = VPPGREInterface(ifname='vppgre0', config)
+ a.add_gre()
+ """
+ self.vpp.api.gre_tunnel_add_del(
+ is_add=True,
+ tunnel={
+ 'src': self.src_address,
+ 'dst': self.dst_address,
+ 'instance': self.instance,
+ 'mode': self.mode,
+ 'type': self.tunnel_type,
+ },
+ )
+ # 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_gre(self):
+ """Delete GRE interface
+ Example:
+ from vyos.ifconfig.vpp import VPPGREInterface
+ a = VPPGREInterface(ifname='vppgre0', config)
+ a.delete_gre()
+ """
+ gre = self.get_gre()
+ if gre:
+ return self.vpp.api.gre_tunnel_add_del(
+ is_add=False,
+ tunnel={'src': gre.tunnel.src, 'dst': gre.tunnel.dst},
+ )
+
+ def kernel_add(self):
+ """Add LCP pair
+ Example:
+ from vyos.ifconfig.vpp import VPPGREInterface
+ a = VPPGREInterface(ifname='vppgre0', config)
+ a.kernel_add()
+ """
+ self.vpp.lcp_pair_add(self.vpp_ifname, self.ifname, 'tun')
+
+ def kernel_delete(self):
+ """Delete LCP pair
+ Example:
+ from vyos.ifconfig.vpp import VPPGREInterface
+ a = VPPGREInterface(ifname='vppgre0', 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 gre interface
+ self.delete_gre()
+
+ def update(self, config):
+ # Add gre interface
+ self.add_gre()
+
+ # 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/interface/__init__.py b/python/vyos/vpp/interface/__init__.py
index 4ae96f486..cdfb0c0b8 100644
--- a/python/vyos/vpp/interface/__init__.py
+++ b/python/vyos/vpp/interface/__init__.py
@@ -18,7 +18,6 @@
from .bridge import BridgeInterface
from .ethernet import EthernetInterface
from .geneve import GeneveInterface
-from .gre import GREInterface
from .interface import Interface
from .wireguard import WireguardInterface
from .xconnect import XconnectInterface
@@ -27,7 +26,6 @@ __all__ = [
'BridgeInterface',
'EthernetInterface',
'GeneveInterface',
- 'GREInterface',
'Interface',
'WireguardInterface',
'XconnectInterface',
diff --git a/python/vyos/vpp/interface/gre.py b/python/vyos/vpp/interface/gre.py
deleted file mode 100644
index bc278d2a0..000000000
--- a/python/vyos/vpp/interface/gre.py
+++ /dev/null
@@ -1,140 +0,0 @@
-# VyOS implementation of VPP GRE 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 GRE interface
- Example:
- from vyos.vpp.interface import gre
- gre.show()
- """
- vpp = VPPControl()
- return vpp.api.gre_tunnel_dump()
-
-
-class GREInterface(Interface):
- """
- Class representing a GRE (Generic Routing Encapsulation) interface.
-
- Attributes:
- ifname (str): The interface name.
- source_address (str): The source IP address for the GRE tunnel.
- remote (str): The remote IP address for the GRE tunnel.
- tunnel_type (str): The type of GRE tunnel. Defaults to 'l3'.
- mode (str): The mode of the GRE tunnel. Options are 'point-to-point' and 'point-to-multipoint'. Defaults to 'point-to-point'.
- kernel_interface (str): The associated kernel interface. Defaults to an empty string.
- instance (int): The instance number derived from the interface name.
- vpp (VPPControl): An instance of the VPPControl class for interacting with the VPP API.
- """
-
- # Mapping of tunnel types https://github.com/FDio/vpp/blob/stable/2406/src/plugins/gre/gre.api#L25-L35
- TUNNEL_TYPE_MAP = {
- 'l3': 0,
- 'teb': 1,
- 'erspan': 2,
- }
-
- MODE_MAP = {
- 'point-to-point': 0,
- 'point-to-multipoint': 1,
- }
-
- def __init__(
- self,
- ifname,
- source_address,
- remote,
- tunnel_type: str = 'l3',
- mode: str = 'point-to-point',
- kernel_interface: str = '',
- state: str = 'up',
- ):
- """
- Initialize a GREInterface instance.
-
- Args:
- ifname (str): The interface name.
- source_address (str): The source IP address for the GRE tunnel.
- remote (str): The remote IP address for the GRE tunnel.
- mode (str): The mode of the GRE tunnel. Options are 'point-to-point' and 'point-to-multipoint'. Defaults to 'point-to-point'.
- tunnel_type (str): The type of GRE tunnel. Defaults to 'l3'.
- kernel_interface (str): The associated kernel interface. Defaults to an empty string.
- state (str): The state of the interface. Defaults to 'up'.
- """
- super().__init__(ifname)
- self.instance = int(ifname.removeprefix('gre'))
- self.ifname = ifname
- self.src_address = source_address
- self.dst_address = remote
- self.tunnel_type = self.TUNNEL_TYPE_MAP[tunnel_type]
- self.mode = self.MODE_MAP[mode]
- self.kernel_interface = kernel_interface
- self.initial_state = state
-
- def add(self):
- """Create GRE interface
- https://github.com/FDio/vpp/blob/stable/2406/src/plugins/gre/gre.api
- Example:
- from vyos.vpp.interface import GREInterface
- a = GREInterface(ifname='gre0', source_address='192.0.2.1', remote='203.0.113.25', tunnel_type='l3')
- a.add()
- """
- self.vpp.api.gre_tunnel_add_del(
- is_add=True,
- tunnel={
- 'src': self.src_address,
- 'dst': self.dst_address,
- 'instance': self.instance,
- 'mode': self.mode,
- 'type': self.tunnel_type,
- },
- )
- # Set interface state
- self.set_state(self.initial_state)
-
- def delete(self):
- """Delete GRE interface
- Example:
- from vyos.vpp.interface import GREInterface
- a = GREInterface(ifname='gre0', source_address='192.0.2.1', remote='203.0.113.25')
- a.delete()
- """
- return self.vpp.api.gre_tunnel_add_del(
- is_add=False, tunnel={'src': self.src_address, 'dst': self.dst_address}
- )
-
- def kernel_add(self):
- """Add LCP pair
- Example:
- from vyos.vpp.interface import GREInterface
- a = GREInterface(ifname='gre0', source_address='192.0.2.1', remote='203.0.113.25')
- a.kernel_add()
- """
- self.vpp.lcp_pair_add(self.ifname, self.kernel_interface, 'tun')
-
- def kernel_delete(self):
- """Delete LCP pair
- Example:
- from vyos.vpp.interface import GREInterface
- a = GREInterface(ifname='gre0', source_address='192.0.2.1', remote='203.0.113.25')
- 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 603f7f90b..dd61d7146 100644
--- a/python/vyos/vpp/interface/xconnect.py
+++ b/python/vyos/vpp/interface/xconnect.py
@@ -41,7 +41,7 @@ class XconnectInterface:
a = XconnectInterface(ifname='xcon0', members=['eth0', 'vxlan0'])
a.add_l2_xconnect()
"""
- interface_transform_filter = ('vxlan', 'gre')
+ interface_transform_filter = ('vxlan', 'geneve')
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'
@@ -72,7 +72,7 @@ class XconnectInterface:
a = XconnectInterface(ifname='xcon0', members=['eth0', 'vxlan0'])
a.del_l2_xconnect()
"""
- interface_transform_filter = ('vxlan', 'gre')
+ interface_transform_filter = ('vxlan', 'geneve')
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'
diff --git a/smoketest/configs/assert/vpp b/smoketest/configs/assert/vpp
index f8cab98f4..1e89dc324 100644
--- a/smoketest/configs/assert/vpp
+++ b/smoketest/configs/assert/vpp
@@ -22,20 +22,14 @@ set system syslog local facility local7 level 'debug'
set interfaces vpp bonding vppbond0 hash-policy 'layer2+3'
set interfaces vpp bonding vppbond0 member interface 'eth4'
set interfaces vpp bonding vppbond0 mode '802.3ad'
-set vpp interfaces gre gre10 description 'Layer-3'
-set vpp interfaces gre gre10 mode 'point-to-point'
-set vpp interfaces gre gre10 remote '192.0.2.2'
-set vpp interfaces gre gre10 source-address '192.0.2.1'
-set vpp interfaces gre gre10 tunnel-type 'l3'
-set vpp interfaces gre gre11 description 'L2-bridge-to-eth2'
-set vpp interfaces gre gre11 remote '192.0.2.123'
-set vpp interfaces gre gre11 source-address '192.0.2.1'
-set vpp interfaces gre gre11 tunnel-type 'teb'
-set vpp interfaces gre gre12 description 'Multipoint'
-set vpp interfaces gre gre12 mode 'point-to-multipoint'
-set vpp interfaces gre gre12 remote '0.0.0.0'
-set vpp interfaces gre gre12 source-address '192.0.2.21'
-set vpp interfaces gre gre12 tunnel-type 'l3'
+set interfaces vpp gre vppgre10 description 'Layer-3'
+set interfaces vpp gre vppgre10 remote '192.0.2.2'
+set interfaces vpp gre vppgre10 source-address '192.0.2.1'
+set interfaces vpp gre vppgre10 tunnel-type 'l3'
+set interfaces vpp gre vppgre11 description 'L2-bridge-to-eth2'
+set interfaces vpp gre vppgre11 remote '192.0.2.123'
+set interfaces vpp gre vppgre11 source-address '192.0.2.1'
+set interfaces vpp gre vppgre11 tunnel-type 'teb'
set interfaces vpp ipip vppipip20 remote '192.0.2.2'
set interfaces vpp ipip vppipip20 source-address '192.0.2.1'
set interfaces vpp loopback vpplo12 description 'Loop12'
diff --git a/smoketest/scripts/cli/test_vpp.py b/smoketest/scripts/cli/test_vpp.py
index 90e4e4538..a16e9af11 100755
--- a/smoketest/scripts/cli/test_vpp.py
+++ b/smoketest/scripts/cli/test_vpp.py
@@ -293,29 +293,16 @@ class TestVPP(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
def test_03_vpp_gre(self):
- interface_gre = 'gre12'
- interface_kernel = 'vpptun12'
- new_interface_kernel = 'vpptun123'
+ gre_path = interfaces_path + ['gre']
+ interface_gre = 'vppgre12'
source_address = '192.0.2.1'
new_source_address = '192.0.2.2'
remote_address = '192.0.2.254'
- kernel_address = '10.0.0.0'
+ address = '10.0.0.0'
- self.cli_set(
- base_path
- + ['interfaces', 'gre', interface_gre, 'source-address', source_address]
- )
- self.cli_set(
- base_path + ['interfaces', 'gre', interface_gre, 'remote', remote_address]
- )
- self.cli_set(
- base_path
- + ['interfaces', 'gre', interface_gre, 'kernel-interface', interface_kernel]
- )
- self.cli_set(
- base_path
- + ['kernel-interfaces', interface_kernel, 'address', f'{kernel_address}/31']
- )
+ self.cli_set(gre_path + [interface_gre, 'source-address', source_address])
+ self.cli_set(gre_path + [interface_gre, 'remote', remote_address])
+ self.cli_set(gre_path + [interface_gre, 'address', f'{address}/31'])
# source address of the tunnel interface should be configured
# expect raise ConfigError
@@ -329,9 +316,9 @@ class TestVPP(VyOSUnitTestSHIM.TestCase):
# commit changes
self.cli_commit()
- self.assertTrue(os.path.isdir(f'/sys/class/net/{interface_kernel}'))
- current_address = get_address(interface_kernel)
- self.assertEqual(kernel_address, current_address)
+ self.assertTrue(os.path.isdir(f'/sys/class/net/{interface_gre}'))
+ current_address = get_address(interface_gre)
+ self.assertEqual(address, current_address)
# check gre interface
_, out = rc_cmd('sudo vppctl show gre tunnel')
@@ -339,10 +326,7 @@ class TestVPP(VyOSUnitTestSHIM.TestCase):
self.assertIn(required_str, out)
# update gre interface
- self.cli_set(
- base_path
- + ['interfaces', 'gre', interface_gre, 'source-address', new_source_address]
- )
+ self.cli_set(gre_path + [interface_gre, 'source-address', new_source_address])
self.cli_set(
['interfaces', 'ethernet', interface, 'address', f'{new_source_address}/24']
@@ -353,46 +337,11 @@ class TestVPP(VyOSUnitTestSHIM.TestCase):
_, out = rc_cmd('sudo vppctl show gre tunnel')
required_str = f'[0] instance 12 src {new_source_address} dst {remote_address}'
self.assertIn(required_str, out)
- self.assertTrue(os.path.isdir(f'/sys/class/net/{interface_kernel}'))
- self.assertEqual(kernel_address, current_address)
-
- # delete gre kernel-interface but do not delete 'vpp kernel-interface'
- # expect raise ConfigError
- self.cli_delete(
- base_path
- + ['interfaces', 'gre', interface_gre, 'kernel-interface', interface_kernel]
- )
- with self.assertRaises(ConfigSessionError):
- self.cli_commit()
-
- # update gre kernel-interface but do not change 'vpp kernel-interface'
- # expect raise ConfigError
- self.cli_set(
- base_path
- + [
- 'interfaces',
- 'gre',
- interface_gre,
- 'kernel-interface',
- new_interface_kernel,
- ]
- )
- with self.assertRaises(ConfigSessionError):
- self.cli_commit()
-
- # delete kernel interface
- self.cli_delete(base_path + ['kernel-interfaces', interface_kernel])
- self.cli_commit()
-
- # delete gre kernel-interface
- self.cli_delete(
- base_path + ['interfaces', 'gre', interface_gre, 'kernel-interface']
- )
- self.cli_commit()
- self.assertFalse(os.path.isdir(f'/sys/class/net/{interface_kernel}'))
+ self.assertTrue(os.path.isdir(f'/sys/class/net/{interface_gre}'))
+ self.assertEqual(address, current_address)
# delete gre interface
- self.cli_delete(base_path + ['interfaces', 'gre', interface_gre])
+ self.cli_delete(gre_path + [interface_gre])
self.cli_commit()
@unittest.skip('Skipping this test geneve index always is 0')
diff --git a/src/conf_mode/vpp.py b/src/conf_mode/vpp.py
index 6d2e2866f..92777a16a 100755
--- a/src/conf_mode/vpp.py
+++ b/src/conf_mode/vpp.py
@@ -612,17 +612,17 @@ def verify(config):
)
# check GRE tunnels as part of the bridge, only tunnel-type teb is allowed
- # set vpp interfaces bridge br1 member interface gre1
- # set vpp interfaces gre gre1 tunnel-type teb
+ # set vpp interfaces bridge br1 member interface vppgre1
+ # set interfaces vpp gre vppgre1 tunnel-type teb
if 'interfaces' in config:
if 'bridge' in config['interfaces']:
for iface, iface_config in config['interfaces']['bridge'].items():
if 'member' in iface_config:
for member in iface_config['member'].get('interface', []):
- if member.startswith('gre'):
+ if member.startswith('vppgre'):
if (
- 'gre' in config['interfaces']
- and config['interfaces']['gre']
+ 'gre' in config['interfaces_vpp']
+ and config['interfaces_vpp']['gre']
.get(member, {})
.get('tunnel_type')
!= 'teb'
@@ -631,29 +631,6 @@ def verify(config):
f'Only tunnel-type teb is allowed for GRE interfaces in bridge {iface}'
)
- # Only one multipoint GRE tunnel is allowed from the same source address
- # set vpp interfaces gre gre0 mode 'point-to-multipoint'
- # set vpp interfaces gre gre0 remote '0.0.0.0'
- # set vpp interfaces gre gre0 source-address '192.0.2.1'
- # set vpp interfaces gre gre1 mode 'point-to-multipoint'
- # set vpp interfaces gre gre1 remote '0.0.0.0'
- # set vpp interfaces gre gre1 source-address '192.0.2.1'
- if 'gre' in config['interfaces']:
- for iface, iface_config in config['interfaces']['gre'].items():
- if iface_config['mode'] == 'point-to-multipoint':
- for other_iface, other_iface_config in config['interfaces'][
- 'gre'
- ].items():
- if (
- other_iface_config['mode'] == 'point-to-multipoint'
- and other_iface_config['source_address']
- == iface_config['source_address']
- and iface != other_iface
- ):
- raise ConfigError(
- 'Only one multipoint GRE tunnel is allowed from the same source address'
- )
-
# Check if deleted interfaces are not xconnect memebrs
for iface_config in config.get('removed_ifaces', []):
if iface_config['iface_name'] in config.get('xconn_members', {}):
diff --git a/src/conf_mode/vpp_interfaces_bridge.py b/src/conf_mode/vpp_interfaces_bridge.py
index d53173f04..edf3f2dd2 100644
--- a/src/conf_mode/vpp_interfaces_bridge.py
+++ b/src/conf_mode/vpp_interfaces_bridge.py
@@ -96,7 +96,7 @@ def verify(config):
# Check if interface exists in vpp before adding to bridge-domain
- allowed_prefixes = ('vppbond', 'gre', 'geneve', 'vpplo', 'vppvxlan')
+ allowed_prefixes = ('vppbond', 'vppgre', 'geneve', 'vpplo', 'vppvxlan')
if 'member' in config:
bvi_exists = False
diff --git a/src/conf_mode/vpp_interfaces_gre.py b/src/conf_mode/vpp_interfaces_gre.py
index 53a423dd9..453845bcf 100644
--- a/src/conf_mode/vpp_interfaces_gre.py
+++ b/src/conf_mode/vpp_interfaces_gre.py
@@ -16,25 +16,20 @@
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-import os
-
from vyos import ConfigError
from vyos.config import Config
-from vyos.configdict import leaf_node_changed
+from vyos.configdict import get_interface_dict
from vyos.configdep import set_dependents, call_dependents
-from vyos.template import is_interface
+from vyos.utils.process import is_systemd_service_active
-from vyos.vpp.interface import GREInterface
+from vyos.ifconfig.vpp import VPPGREInterface
from vyos.vpp.config_deps import deps_xconnect_dict
from vyos.vpp.config_verify import (
- verify_vpp_remove_kernel_interface,
- verify_vpp_change_kernel_interface,
verify_vpp_remove_xconnect_interface,
- verify_vpp_exists_kernel_interface,
verify_vpp_tunnel_source_address,
)
-from vyos.vpp.utils import cli_ifaces_lcp_kernel_list, cli_ethernet_with_vifs_ifaces
+from vyos.vpp.utils import cli_ethernet_with_vifs_ifaces
def get_config(config=None) -> dict:
@@ -50,55 +45,14 @@ def get_config(config=None) -> dict:
else:
conf = Config()
- base = ['vpp', 'interfaces', 'gre']
- base_kernel_interfaces = ['vpp', 'kernel-interfaces']
-
- ifname = os.environ['VYOS_TAGNODE_VALUE']
+ base = ['interfaces', 'vpp', 'gre']
- # Get config_dict with default values
- config = conf.get_config_dict(
- base + [ifname],
- key_mangling=('-', '_'),
- get_first_key=True,
- no_tag_node_value_mangle=True,
- with_defaults=True,
- with_recursive_defaults=True,
- )
+ ifname, config = get_interface_dict(conf, base)
- if not conf.exists(['vpp']):
+ if not conf.exists(['vpp']) and not conf.exists(base):
config['remove_vpp'] = True
return config
- # Get effective config as we need full dicitonary per interface delete
- effective_config = conf.get_config_dict(
- base + [ifname],
- key_mangling=('-', '_'),
- effective=True,
- get_first_key=True,
- no_tag_node_value_mangle=True,
- )
-
- if effective_config:
- config.update({'effective': effective_config})
-
- if not conf.exists(base + [ifname]):
- config['remove'] = True
-
- # Get global 'vpp kernel-interfaces' for verify
- config['vpp_kernel_interfaces'] = conf.get_config_dict(
- base_kernel_interfaces,
- key_mangling=('-', '_'),
- get_first_key=True,
- no_tag_node_value_mangle=True,
- )
-
- tmp = leaf_node_changed(conf, base + [ifname, 'kernel-interface'])
- if tmp:
- config['kernel_interface_removed'] = tmp
-
- # list of all kernel interfaces `vpp interface xxx kernel-interface xxx`
- config['candidate_kernel_interfaces'] = cli_ifaces_lcp_kernel_list(conf)
-
# list of all Ethernet interfaces with vifs
config['vpp_ether_vif_ifaces'] = cli_ethernet_with_vifs_ifaces(conf)
@@ -108,11 +62,23 @@ def get_config(config=None) -> dict:
for xconn_iface in config['xconn_members'][ifname]:
set_dependents('vpp_interfaces_xconnect', conf, xconn_iface)
- if effective_config.get('kernel_interface'):
- if conf.exists(base + [ifname, 'kernel-interface']):
- iface = config.get('kernel_interface')
- if conf.exists(['vpp', 'kernel-interfaces', iface]):
- set_dependents('vpp_kernel_interface', conf, iface)
+ # Get 'vpp settings' config
+ config['vpp_settings'] = conf.get_config_dict(
+ ['vpp', 'settings'],
+ key_mangling=('-', '_'),
+ get_first_key=True,
+ no_tag_node_value_mangle=True,
+ )
+
+ # Get all gre interfaces config
+ config['gre_interfaces'] = conf.get_config_dict(
+ base,
+ key_mangling=('-', '_'),
+ get_first_key=True,
+ no_tag_node_value_mangle=True,
+ with_defaults=True,
+ with_recursive_defaults=True,
+ )
# NAT dependency
if conf.exists(['vpp', 'nat', 'nat44']):
@@ -124,7 +90,6 @@ def get_config(config=None) -> dict:
if conf.exists(['vpp', 'acl']):
set_dependents('vpp_acl', conf)
- config['ifname'] = ifname
return config
@@ -133,19 +98,19 @@ def verify(config):
if 'remove_vpp' in config:
return None
- # Verify that removed kernel interface is not used in 'vpp kernel-interfaces'.
- # vpp interfaces gre greX kernel-interface vpp-tunX
- # vpp kernel-interface vpp-tunX
- verify_vpp_remove_kernel_interface(config)
-
verify_vpp_remove_xconnect_interface(config)
# config removed
- if 'remove' in config:
+ if 'deleted' in config:
return None
+ if not is_systemd_service_active('vpp.service'):
+ raise ConfigError(
+ 'Cannot configure VPP GRE interface: vpp.service is not running'
+ )
+
# source-address and remote are mandatory options
- required_keys = {'source_address', 'remote', 'mode', 'tunnel_type'}
+ required_keys = {'source_address', 'remote', 'tunnel_type'}
if not all(key in config for key in required_keys):
missing_keys = required_keys - set(config.keys())
raise ConfigError(
@@ -157,17 +122,28 @@ def verify(config):
if config.get('source_address') == config.get('remote'):
raise ConfigError('Remote address must not be the same as source address')
- # check multipoint mode
- if config.get('mode') == 'point-to-multipoint':
- # For multipoint mode, remote IP must be 0.0.0.0
- if config.get('remote') != '0.0.0.0':
- raise ConfigError('For point-to-multipoint mode, remote must be 0.0.0.0')
-
- # Change 'vpp interfaces gre greX kernel-interface vpp-tunX'
- # => 'vpp interfaces gre greX kernel-interface vpp-tunY'
- # check if we have kernel interface config 'vpp kernel-interface vpp-tunX'
- verify_vpp_change_kernel_interface(config)
- verify_vpp_exists_kernel_interface(config)
+ # Disable checks as point-to-multipoint mode does not work without 'teib' feature that is not implemented yet
+ # # check multipoint mode
+ # if config.get('mode') == 'point-to-multipoint':
+ # # For multipoint mode, remote IP must be 0.0.0.0
+ # if config.get('remote') != '0.0.0.0':
+ # raise ConfigError('For point-to-multipoint mode, remote must be 0.0.0.0')
+ #
+ # # Only one multipoint GRE tunnel is allowed from the same source address
+ # # set interfaces vpp gre vppgre0 mode 'point-to-multipoint'
+ # # set interfaces vpp gre vppgre0 remote '0.0.0.0'
+ # # set interfaces vpp gre vppgre0 source-address '192.0.2.1'
+ # # set interfaces vpp gre vppgre1 mode 'point-to-multipoint'
+ # # set interfaces vpp gre vppgre1 remote '0.0.0.0'
+ # # set interfaces vpp gre vppgre1 source-address '192.0.2.1'
+ # for other_iface, other_iface_config in config['gre_interfaces'].items():
+ # if other_iface == config['ifname']:
+ # continue
+ # if other_iface_config['mode'] == 'point-to-multipoint':
+ # if config['source_address'] == other_iface_config.get('source_address'):
+ # raise ConfigError(
+ # 'Only one multipoint GRE tunnel is allowed from the same source address'
+ # )
def generate(config):
@@ -179,32 +155,13 @@ def apply(config):
return None
ifname = config.get('ifname')
- # Delete interface
- if 'effective' in config:
- remove_config = config.get('effective')
- src_addr = remove_config.get('source_address')
- dst_addr = remove_config.get('remote')
- i = GREInterface(ifname, src_addr, dst_addr)
- i.delete()
-
- if 'remove' in config:
- return None
+ gre = VPPGREInterface(ifname, config)
+ gre.remove()
- # Add interface
- src_addr = config.get('source_address')
- dst_addr = config.get('remote')
- kernel_interface = config.get('kernel_interface', '')
- mode = config.get('mode')
- tunnel_type = config.get('tunnel_type')
- state = 'up' if 'disable' not in config else 'down'
- i = GREInterface(
- ifname, src_addr, dst_addr, tunnel_type, mode, kernel_interface, state
- )
- i.add()
+ if 'deleted' in config:
+ return
- # Add kernel-interface (LCP) if interface is not exist
- if 'kernel_interface' in config and not is_interface(kernel_interface):
- i.kernel_add()
+ gre.update(config)
call_dependents()
diff --git a/src/migration-scripts/vpp/5-to-6 b/src/migration-scripts/vpp/5-to-6
index 23b2d4eaa..03c20d970 100644
--- a/src/migration-scripts/vpp/5-to-6
+++ b/src/migration-scripts/vpp/5-to-6
@@ -45,6 +45,8 @@
#
# Migrate loopback interface from vpp section to 'interfaces vpp loopback' (T8324)
#
+# Migrate gre interface to 'interfaces vpp gre', remove interfaces with mode "point-to-multipoint" (T8325)
+#
from vyos.configtree import ConfigTree
@@ -463,6 +465,37 @@ def _migrate_vpp_loopback_interface(config: ConfigTree) -> None:
config.delete(['vpp', 'interfaces'])
+def _migrate_vpp_gre_interface(config: ConfigTree) -> None:
+ base = ['vpp', 'interfaces', 'gre']
+ new_base = ['interfaces', 'vpp', 'gre']
+ kernel_interface_base = ['vpp', 'kernel-interfaces']
+
+ if not config.exists(base):
+ return
+
+ config.set(new_base)
+
+ for ifname in config.list_nodes(base):
+ if config.exists(base + [ifname, 'mode']):
+ if config.return_value(base + [ifname, 'mode']) == 'point-to-multipoint':
+ config.delete(base + [ifname])
+ continue
+ config.delete(base + [ifname, 'mode'])
+
+ _migrate_interface(config, 'gre', ifname)
+
+ _migrate_members_bridge(config, ifname)
+ _migrate_members_xconnect(config, ifname)
+
+ config.delete(base)
+
+ if config.exists(kernel_interface_base) and len(config.list_nodes(kernel_interface_base)) == 0:
+ config.delete(['vpp', 'kernel-interfaces'])
+
+ if len(config.list_nodes(['vpp', 'interfaces'])) == 0:
+ config.delete(['vpp', 'interfaces'])
+
+
def migrate(config: ConfigTree) -> None:
if not config.exists(['vpp']):
# Nothing to do
@@ -482,3 +515,4 @@ def migrate(config: ConfigTree) -> None:
_migrate_vpp_vxlan_interface(config)
_migrate_vpp_ipip_interface(config)
_migrate_vpp_loopback_interface(config)
+ _migrate_vpp_gre_interface(config)