summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorNataliia S. <81954790+natali-rs1985@users.noreply.github.com>2025-11-04 15:15:59 +0200
committerGitHub <noreply@github.com>2025-11-04 15:15:59 +0200
commit4f9c241db48928f974a32bc6901b9ed4cf2ce20e (patch)
treed781bbe53e9769cf669d8d792b5c0519e67a58c2 /python
parente1b7b865a63454ae4b8f840c94ab599633faaf7f (diff)
parent73b7431862d8da2e8063a6062f29fd0f65fdd210 (diff)
downloadvyos-1x-4f9c241db48928f974a32bc6901b9ed4cf2ce20e.tar.gz
vyos-1x-4f9c241db48928f974a32bc6901b9ed4cf2ce20e.zip
Merge pull request #4747 from natali-rs1985/T7789
T7789: T7661: VPP prevent failing to load XDP in clouds (ena/gve drivers)
Diffstat (limited to 'python')
-rw-r--r--python/vyos/ethtool.py23
-rw-r--r--python/vyos/ifconfig/ethernet.py17
-rw-r--r--python/vyos/vpp/control_host.py38
-rw-r--r--python/vyos/vpp/control_vpp.py2
4 files changed, 79 insertions, 1 deletions
diff --git a/python/vyos/ethtool.py b/python/vyos/ethtool.py
index 6c362163c..22e066def 100644
--- a/python/vyos/ethtool.py
+++ b/python/vyos/ethtool.py
@@ -59,6 +59,7 @@ class Ethtool:
_ring_buffer = None
_driver_name = None
_flow_control = None
+ _channels = ''
def __init__(self, ifname):
# Get driver used for interface
@@ -111,6 +112,11 @@ class Ethtool:
if not bool(err):
self._flow_control = loads(out)[0]
+ # Get information about NIC channels
+ out, err = popen(f'ethtool --show-channels {ifname}')
+ if not bool(err):
+ self._channels = out.lower()
+
def check_auto_negotiation_supported(self):
""" Check if the NIC supports changing auto-negotiation """
return self._base_settings['supports-auto-negotiation']
@@ -199,3 +205,20 @@ class Ethtool:
'flow-control settings!')
return 'on' if bool(self._flow_control['autonegotiate']) else 'off'
+
+ def get_channels(self, rx_tx_comb):
+ """
+ Get both the pre-set maximum and current value for a given channel type.
+
+ Args:
+ rx_tx_comb (str): Channel type, one of "rx", "tx", or "combined".
+
+ Returns:
+ list[int]: [maximum, current] values for the channel,
+ or an empty list if not supported.
+ """
+ if rx_tx_comb not in ['rx', 'tx', 'combined']:
+ raise ValueError('Channel type must be either "rx", "tx" or "combined"')
+ matches = re.findall(rf'{rx_tx_comb}:\s+(\d+)', self._channels)
+
+ return [int(value) for value in matches]
diff --git a/python/vyos/ifconfig/ethernet.py b/python/vyos/ifconfig/ethernet.py
index 6c7b230ca..70da837b9 100644
--- a/python/vyos/ifconfig/ethernet.py
+++ b/python/vyos/ifconfig/ethernet.py
@@ -455,6 +455,23 @@ class EthernetIf(Interface):
print(f'could not set "{rx_tx}" ring-buffer for {ifname}')
return output
+ def set_channels(self, rx_tx_comb, queues):
+ """
+ Example:
+ >>> from vyos.ifconfig import EthernetIf
+ >>> i = EthernetIf('eth0')
+ >>> i.set_channels('rx', 2)
+ """
+ ifname = self.config['ifname']
+ cmd = f'ethtool --set-channels {ifname} {rx_tx_comb} {queues}'
+ output, code = self._popen(cmd)
+ # ethtool error codes:
+ # 80 - value already setted
+ # 81 - does not possible to set value
+ if code and code != 80:
+ print(f'could not set "{rx_tx_comb}" channel for {ifname}')
+ return output
+
def set_switchdev(self, enable):
ifname = self.config['ifname']
addr, code = self._popen(
diff --git a/python/vyos/vpp/control_host.py b/python/vyos/vpp/control_host.py
index db1a492c9..2ebfd180b 100644
--- a/python/vyos/vpp/control_host.py
+++ b/python/vyos/vpp/control_host.py
@@ -24,6 +24,7 @@ from time import sleep
from pyroute2 import IPRoute
from vyos.ethtool import Ethtool
+from vyos.ifconfig import EthernetIf
from vyos.vpp.utils import EthtoolGDrvinfo
@@ -376,3 +377,40 @@ def flush_ip(iface_name: str) -> None:
"""
iproute = IPRoute()
iproute.flush_addr(label=iface_name)
+
+
+def get_eth_channels(iface_name: str) -> dict:
+ """
+ Get the current hardware queue counts for channels of an interface using ethtool.
+
+ Args:
+ iface_name (str): name of an interface
+
+ Returns:
+ dict: Mapping of channel types to their current values:
+ - 'rx' (int | None): RX channel count.
+ - 'tx' (int | None): TX channel count.
+ - 'combined' (int | None): Combined channel count.
+ Returns None if the channel type is not supported.
+ """
+ ethtool = Ethtool(iface_name)
+
+ channels = {}
+ for channel in ['rx', 'tx', 'combined']:
+ queues_list = ethtool.get_channels(channel)
+ channels[channel] = queues_list[-1] if (len(queues_list) == 2) else None
+
+ return channels
+
+
+def set_eth_channels(iface_name: str, channels: dict) -> None:
+ """Configure the number of RX, TX, or combined channels for an interface.
+
+ Args:
+ iface_name (str): name of an interface
+ channels (dict): channels to set
+ """
+ interface = EthernetIf(iface_name)
+ for channel, value in channels.items():
+ if value:
+ interface.set_channels(channel, value)
diff --git a/python/vyos/vpp/control_vpp.py b/python/vyos/vpp/control_vpp.py
index cb8da50a6..2ee253b45 100644
--- a/python/vyos/vpp/control_vpp.py
+++ b/python/vyos/vpp/control_vpp.py
@@ -351,7 +351,7 @@ class VPPControl:
self,
host_if: str,
name: str,
- rxq_num: int = 0,
+ rxq_num: int = 65535,
rxq_size: int = 0,
txq_size: int = 0,
mode: Literal['auto', 'copy', 'zero-copy'] = 'auto',