summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNataliia Solomko <natalirs1985@gmail.com>2026-03-23 13:36:00 +0200
committerNataliia Solomko <natalirs1985@gmail.com>2026-03-23 13:36:00 +0200
commitd922f888dc822cc4e3b7ce70a4402ece7eef6e41 (patch)
treef5a8072535f189c3985929280434d7d2f395ed60
parent42b2376e030f85b602862632b3e8e8534a3a5ef1 (diff)
downloadvyos-1x-d922f888dc822cc4e3b7ce70a4402ece7eef6e41.tar.gz
vyos-1x-d922f888dc822cc4e3b7ce70a4402ece7eef6e41.zip
vpp: T8355: Set MTU for vpp interfaces
-rw-r--r--interface-definitions/vpp_interface_bonding.xml.in3
-rw-r--r--interface-definitions/vpp_interface_gre.xml.in3
-rw-r--r--interface-definitions/vpp_interface_ipip.xml.in3
-rw-r--r--interface-definitions/vpp_interface_vxlan.xml.in3
-rw-r--r--python/vyos/ifconfig/vpp/bond.py3
-rw-r--r--python/vyos/ifconfig/vpp/gre.py5
-rw-r--r--python/vyos/ifconfig/vpp/interface.py17
-rw-r--r--python/vyos/ifconfig/vpp/ipip.py3
-rw-r--r--python/vyos/ifconfig/vpp/loopback.py2
-rw-r--r--python/vyos/ifconfig/vpp/vxlan.py2
-rw-r--r--python/vyos/utils/network.py25
-rw-r--r--python/vyos/vpp/control_vpp.py7
-rw-r--r--src/conf_mode/vpp_interfaces_bonding.py17
-rw-r--r--src/conf_mode/vpp_interfaces_gre.py3
-rw-r--r--src/conf_mode/vpp_interfaces_ipip.py3
-rw-r--r--src/conf_mode/vpp_interfaces_vxlan.py28
16 files changed, 124 insertions, 3 deletions
diff --git a/interface-definitions/vpp_interface_bonding.xml.in b/interface-definitions/vpp_interface_bonding.xml.in
index 9f114d157..78166e306 100644
--- a/interface-definitions/vpp_interface_bonding.xml.in
+++ b/interface-definitions/vpp_interface_bonding.xml.in
@@ -108,6 +108,9 @@
</node>
#include <include/interface/address-ipv4-ipv6.xml.i>
#include <include/interface/mtu-68-16000.xml.i>
+ <leafNode name="mtu">
+ <defaultValue>1500</defaultValue>
+ </leafNode>
#include <include/vpp/vif.xml.i>
</children>
</tagNode>
diff --git a/interface-definitions/vpp_interface_gre.xml.in b/interface-definitions/vpp_interface_gre.xml.in
index 0ac3fdf1f..a0228420a 100644
--- a/interface-definitions/vpp_interface_gre.xml.in
+++ b/interface-definitions/vpp_interface_gre.xml.in
@@ -76,6 +76,9 @@
#include <include/interface/tunnel-remote.xml.i>
#include <include/interface/address-ipv4-ipv6.xml.i>
#include <include/interface/mtu-68-16000.xml.i>
+ <leafNode name="mtu">
+ <defaultValue>1476</defaultValue>
+ </leafNode>
</children>
</tagNode>
</children>
diff --git a/interface-definitions/vpp_interface_ipip.xml.in b/interface-definitions/vpp_interface_ipip.xml.in
index c965c531c..a214f728e 100644
--- a/interface-definitions/vpp_interface_ipip.xml.in
+++ b/interface-definitions/vpp_interface_ipip.xml.in
@@ -24,6 +24,9 @@
#include <include/interface/tunnel-remote.xml.i>
#include <include/interface/address-ipv4-ipv6.xml.i>
#include <include/interface/mtu-68-16000.xml.i>
+ <leafNode name="mtu">
+ <defaultValue>1476</defaultValue>
+ </leafNode>
</children>
</tagNode>
</children>
diff --git a/interface-definitions/vpp_interface_vxlan.xml.in b/interface-definitions/vpp_interface_vxlan.xml.in
index 9ba90e2a0..1de141b1e 100644
--- a/interface-definitions/vpp_interface_vxlan.xml.in
+++ b/interface-definitions/vpp_interface_vxlan.xml.in
@@ -25,6 +25,9 @@
#include <include/vni.xml.i>
#include <include/interface/address-ipv4-ipv6.xml.i>
#include <include/interface/mtu-68-16000.xml.i>
+ <leafNode name="mtu">
+ <defaultValue>1450</defaultValue>
+ </leafNode>
</children>
</tagNode>
</children>
diff --git a/python/vyos/ifconfig/vpp/bond.py b/python/vyos/ifconfig/vpp/bond.py
index 75849a620..a1c6f2ef3 100644
--- a/python/vyos/ifconfig/vpp/bond.py
+++ b/python/vyos/ifconfig/vpp/bond.py
@@ -148,5 +148,8 @@ class VPPBondInterface(Interface, VPPInterface):
if rx_mode:
self.set_rx_mode(rx_mode)
+ # Apply VPP-specific interface settings
+ VPPInterface.update(self, config)
+
# Apply all settings to the lcp pair (kernel) interface
super().update(config)
diff --git a/python/vyos/ifconfig/vpp/gre.py b/python/vyos/ifconfig/vpp/gre.py
index 0cec5e3c9..074977500 100644
--- a/python/vyos/ifconfig/vpp/gre.py
+++ b/python/vyos/ifconfig/vpp/gre.py
@@ -141,4 +141,7 @@ class VPPGREInterface(Interface, VPPInterface):
if rx_mode:
self.set_rx_mode(rx_mode)
- super().update(config)
+ # Apply VPP-specific interface settings
+ VPPInterface.update(self, config)
+
+ super().update(config) \ No newline at end of file
diff --git a/python/vyos/ifconfig/vpp/interface.py b/python/vyos/ifconfig/vpp/interface.py
index 1b87af4d2..17a897f74 100644
--- a/python/vyos/ifconfig/vpp/interface.py
+++ b/python/vyos/ifconfig/vpp/interface.py
@@ -54,3 +54,20 @@ class VPPInterface:
lcp_name = lcp_pair.get('vpp_name_kernel')
if lcp_name:
self.vpp.iface_rxmode(lcp_name, rx_mode)
+
+ def set_mtu_vpp(self, mtu):
+ # Set MTU for the VPP interface
+ self.vpp.set_iface_mtu(self.vpp_ifname, mtu)
+
+ # Set MTU for the LCP pair interface
+ 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.set_iface_mtu(lcp_name, mtu)
+
+ def update(self, config):
+ # Set MTU
+ if 'mtu' in config:
+ mtu = int(config['mtu'])
+ self.set_mtu_vpp(mtu)
diff --git a/python/vyos/ifconfig/vpp/ipip.py b/python/vyos/ifconfig/vpp/ipip.py
index fff79fd43..baec9f1c7 100644
--- a/python/vyos/ifconfig/vpp/ipip.py
+++ b/python/vyos/ifconfig/vpp/ipip.py
@@ -105,5 +105,8 @@ class VPPIPIPInterface(Interface, VPPInterface):
if rx_mode:
self.set_rx_mode(rx_mode)
+ # Apply VPP-specific interface settings
+ VPPInterface.update(self, config)
+
# Apply all settings to the lcp pair (kernel) interface
super().update(config)
diff --git a/python/vyos/ifconfig/vpp/loopback.py b/python/vyos/ifconfig/vpp/loopback.py
index 36a30cb58..5ef7ead23 100644
--- a/python/vyos/ifconfig/vpp/loopback.py
+++ b/python/vyos/ifconfig/vpp/loopback.py
@@ -101,5 +101,7 @@ class VPPLoopbackInterface(Interface, VPPInterface):
if rx_mode:
self.set_rx_mode(rx_mode)
+ VPPInterface.update(self, config)
+
# Apply all settings to the lcp pair (kernel) interface
super().update(config)
diff --git a/python/vyos/ifconfig/vpp/vxlan.py b/python/vyos/ifconfig/vpp/vxlan.py
index 8ca9bee70..da4e7ed50 100644
--- a/python/vyos/ifconfig/vpp/vxlan.py
+++ b/python/vyos/ifconfig/vpp/vxlan.py
@@ -122,4 +122,6 @@ class VPPVXLANInterface(Interface, VPPInterface):
if rx_mode:
self.set_rx_mode(rx_mode)
+ VPPInterface.update(self, config)
+
super().update(config)
diff --git a/python/vyos/utils/network.py b/python/vyos/utils/network.py
index 217428a21..de283e546 100644
--- a/python/vyos/utils/network.py
+++ b/python/vyos/utils/network.py
@@ -696,3 +696,28 @@ def is_valid_ipv6_address_or_range(addr: str) -> bool:
return ip_network(addr).version == 6
except:
return False
+
+
+def get_interfaces_by_ip(ip_address: str) -> list:
+ """
+ Return a list of all interface names assigned the given IP address.
+ Args:
+ ip_address (str): The IP address to search for.
+ Returns:
+ list: List of interface names (str) that have the given IP address assigned.
+ Returns an empty list if no interface has the IP assigned.
+ """
+ import netifaces
+ from vyos.template import is_ipv6
+
+ addr_type = AF_INET
+ if is_ipv6(ip_address):
+ addr_type = AF_INET6
+
+ ifaces = []
+ for interface in netifaces.interfaces():
+ addresses = netifaces.ifaddresses(interface)
+ for addr_info in addresses.get(addr_type, []):
+ if addr_info.get('addr') == ip_address:
+ ifaces.append(interface)
+ return ifaces
diff --git a/python/vyos/vpp/control_vpp.py b/python/vyos/vpp/control_vpp.py
index 2daaed423..5f3a18848 100644
--- a/python/vyos/vpp/control_vpp.py
+++ b/python/vyos/vpp/control_vpp.py
@@ -422,8 +422,11 @@ class VPPControl:
mtu (int): MTU
"""
iface_index = self.get_sw_if_index(iface_name_vpp)
- api_call_args: dict[str, str | int] = {'sw_if_index': iface_index, 'mtu': mtu}
- return self.__vpp_api_client.api.hw_interface_set_mtu(**api_call_args)
+ api_call_args: dict[str, int | list[int]] = {
+ 'sw_if_index': iface_index,
+ 'mtu': [mtu, 0, 0, 0],
+ }
+ return self.__vpp_api_client.api.sw_interface_set_mtu(**api_call_args)
@_Decorators.api_call
def get_sw_if_dev_type(self, ifname: str) -> int | None:
diff --git a/src/conf_mode/vpp_interfaces_bonding.py b/src/conf_mode/vpp_interfaces_bonding.py
index 8d9930a20..80356ce2b 100644
--- a/src/conf_mode/vpp_interfaces_bonding.py
+++ b/src/conf_mode/vpp_interfaces_bonding.py
@@ -19,10 +19,12 @@
from vyos.config import Config
from vyos.configdict import get_interface_dict
from vyos.configdep import set_dependents, call_dependents
+from vyos.configverify import verify_mtu_ipv6
from vyos import ConfigError
from vyos.utils.assertion import assert_mac
from vyos.utils.process import is_systemd_service_active
+from vyos.ifconfig import Interface
from vyos.ifconfig.vpp import VPPBondInterface
from vyos.vpp.config_deps import deps_bond_dict
from vyos.vpp.config_deps import deps_bridge_dict
@@ -174,6 +176,19 @@ def verify(config):
f'it already belongs to bridge interface: {", ".join(bridge_members)}.'
)
+ if mtu := config.get('mtu'):
+ mtu = int(mtu)
+ max_mtu = Interface(iface).get_max_mtu()
+ min_mtu = Interface(iface).get_min_mtu()
+ if mtu > max_mtu:
+ raise ConfigError(
+ f'Configured MTU is greater than member interface "{iface}" maximum of {max_mtu}!'
+ )
+ if mtu < min_mtu:
+ raise ConfigError(
+ f'Configured MTU is less than member interface "{iface}" minimum of {min_mtu}!'
+ )
+
if 'mac' in config:
mac = config['mac']
try:
@@ -190,6 +205,8 @@ def verify(config):
f'Cannot remove interface {vif_iface}: it is still in use by the PPPoE server'
)
+ verify_mtu_ipv6(config)
+
def generate(config):
pass
diff --git a/src/conf_mode/vpp_interfaces_gre.py b/src/conf_mode/vpp_interfaces_gre.py
index 1258f906c..3756449a2 100644
--- a/src/conf_mode/vpp_interfaces_gre.py
+++ b/src/conf_mode/vpp_interfaces_gre.py
@@ -21,6 +21,7 @@ from vyos import ConfigError
from vyos.config import Config
from vyos.configdict import get_interface_dict
from vyos.configdep import set_dependents, call_dependents
+from vyos.configverify import verify_mtu_ipv6
from vyos.utils.process import is_systemd_service_active
from vyos.ifconfig.vpp import VPPGREInterface
@@ -128,6 +129,8 @@ def verify(config):
if config.get('source_address') == config.get('remote'):
raise ConfigError('Remote address must not be the same as source address')
+ verify_mtu_ipv6(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':
diff --git a/src/conf_mode/vpp_interfaces_ipip.py b/src/conf_mode/vpp_interfaces_ipip.py
index d029f3619..dd4a19e36 100644
--- a/src/conf_mode/vpp_interfaces_ipip.py
+++ b/src/conf_mode/vpp_interfaces_ipip.py
@@ -21,6 +21,7 @@ from vyos import ConfigError
from vyos.config import Config
from vyos.configdict import get_interface_dict
from vyos.configdep import set_dependents, call_dependents
+from vyos.configverify import verify_mtu_ipv6
from vyos.utils.process import is_systemd_service_active
from vyos.ifconfig.vpp import VPPIPIPInterface
@@ -102,6 +103,8 @@ def verify(config):
if config.get('source_address') == config.get('remote'):
raise ConfigError('Remote address must not be the same as source address')
+ verify_mtu_ipv6(config)
+
def generate(config):
pass
diff --git a/src/conf_mode/vpp_interfaces_vxlan.py b/src/conf_mode/vpp_interfaces_vxlan.py
index 38349cb4c..ac9a9517b 100644
--- a/src/conf_mode/vpp_interfaces_vxlan.py
+++ b/src/conf_mode/vpp_interfaces_vxlan.py
@@ -18,9 +18,14 @@
from vyos import ConfigError
+from vyos.base import Warning
from vyos.config import Config
from vyos.configdict import get_interface_dict
from vyos.configdep import set_dependents, call_dependents
+from vyos.configverify import verify_mtu_ipv6
+from vyos.ifconfig import Interface
+from vyos.template import is_ipv6
+from vyos.utils.network import get_interfaces_by_ip
from vyos.utils.process import is_systemd_service_active
from vyos.ifconfig.vpp import VPPVXLANInterface
@@ -117,6 +122,29 @@ def verify(config):
if config.get('source_address') == config.get('remote'):
raise ConfigError('Remote address must not be the same as source address')
+ # VXLAN adds at least an overhead of 50 bytes - we need to check the
+ # underlying device if our VXLAN package is not going to be fragmented!
+ source_address = config['source_address']
+ vxlan_overhead = 50
+ if is_ipv6(source_address):
+ # IPv6 adds an extra 20 bytes overhead because the IPv6 header is 20
+ # bytes larger than the IPv4 header - assuming no extra options are
+ # in use.
+ vxlan_overhead += 20
+
+ ifaces_with_ip = get_interfaces_by_ip(source_address)
+ vpp_ifaces = config['vpp_ether_vif_ifaces']
+ matching_iface = next((iface for iface in ifaces_with_ip if iface in vpp_ifaces))
+
+ lower_mtu = Interface(matching_iface).get_mtu()
+ if lower_mtu < (int(config['mtu']) + vxlan_overhead):
+ Warning(
+ f'Underlying device MTU is too small ({lower_mtu} bytes) '
+ f'for VXLAN overhead ({vxlan_overhead} bytes!)'
+ )
+
+ verify_mtu_ipv6(config)
+
def generate(config):
pass