diff options
| author | Nataliia S. <81954790+natali-rs1985@users.noreply.github.com> | 2025-11-04 15:15:59 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-11-04 15:15:59 +0200 |
| commit | 4f9c241db48928f974a32bc6901b9ed4cf2ce20e (patch) | |
| tree | d781bbe53e9769cf669d8d792b5c0519e67a58c2 /python | |
| parent | e1b7b865a63454ae4b8f840c94ab599633faaf7f (diff) | |
| parent | 73b7431862d8da2e8063a6062f29fd0f65fdd210 (diff) | |
| download | vyos-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.py | 23 | ||||
| -rw-r--r-- | python/vyos/ifconfig/ethernet.py | 17 | ||||
| -rw-r--r-- | python/vyos/vpp/control_host.py | 38 | ||||
| -rw-r--r-- | python/vyos/vpp/control_vpp.py | 2 |
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', |
