Skip to content

Commit 65450bf

Browse files
authored
Merge branch 'main' into fix__fix_regex_to_get_vfs_details_properly
2 parents 42a910e + 9c13b17 commit 65450bf

File tree

15 files changed

+626
-26
lines changed

15 files changed

+626
-26
lines changed

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,22 @@
22

33
<!-- version list -->
44

5+
## v14.3.1 (2025-10-29)
6+
7+
### Bug Fixes
8+
9+
- Add optional additional parameters for bridge creation
10+
([`0a7533d`](https://github.com/intel/mfd-network-adapter/commit/0a7533d55860961b54859c122dba8adc743ff263))
11+
12+
13+
## v14.3.0 (2025-10-27)
14+
15+
### Features
16+
17+
- Add devlink commands and RSS queues settings
18+
([`4cd5f2c`](https://github.com/intel/mfd-network-adapter/commit/4cd5f2c05357dfa895e518230de1df9f4f229aae))
19+
20+
521
## v14.2.0 (2025-10-15)
622

723
### Features

README.md

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ interfaces = owner.get_interfaces()
8787
```
8888
## Exceptions raised by MFD-Network-Adapter module
8989
- related to module: `NetworkAdapterModuleException`
90-
- related to Network Interface: `InterfaceNameNotFound`, `IPException`, `IPAddressesNotFound`, `NetworkQueuesException`, `RDMADeviceNotFound`, `NumaNodeException`, `DriverInfoNotFound`, `FirmwareVersionNotFound`
90+
- related to Network Interface: `InterfaceNameNotFound`, `IPException`, `IPAddressesNotFound`, `NetworkQueuesException`, `RDMADeviceNotFound`, `NumaNodeException`, `DriverInfoNotFound`, `FirmwareVersionNotFound`, `VirtualFunctionNotFoundException`, `HypervisorNotSupportedException`, `NetworkAdapterConfigurationException`, `NetworkInterfaceNotSupported`
9191
- related to NetworkInterface's features: `VirtualizationFeatureException`
9292
-
9393
## Classes
@@ -650,6 +650,11 @@ Value of param will be prepared for update for all interfaces using <driver_name
650650
prepare_values_sharing_same_driver(*, driver_name: str, param: str, value: int) -> str
651651
```
652652

653+
[Linux] Enable or disable SRIOV drivers auto probe.
654+
```python
655+
set_sriov_driver_autoprobe(self, state: bool) -> None
656+
```
657+
653658
[Windows]
654659

655660
`change_state_family_interfaces(*, driver_filename: str, enable: State.ENABLED) -> None`
@@ -927,6 +932,16 @@ verify_vmdq(interface: "NetworkInterface", desired_value: int) -> None
927932
get_vm_vf_ids(self, vm_name: str, interface: "ESXiNetworkInterface") -> list[int]
928933
```
929934

935+
[Linux] Set number of MSI-X vectors for PF interface.
936+
```python
937+
set_msix_vectors_count(self, count: int, method: MethodType = MethodType.DEVLINK) -> None
938+
```
939+
940+
[Linux] Get number of MSI-X vectors of PF interface.
941+
```python
942+
get_msix_vectors_count(self, method: MethodType = MethodType.DEVLINK) -> int
943+
```
944+
930945
### Queue
931946

932947
[L] Get number of queues from proc interrupts
@@ -1259,6 +1274,8 @@ class NetworkInterface(ABC):
12591274

12601275
- `get_number_of_ports() -> int'` - Get number of ports in tested adapter.
12611276

1277+
- `reload_adapter_devlink() -> None` - Reload adapter via devlink.
1278+
12621279
- `restart() -> None` - Restart interface.
12631280

12641281
#### Additional methods - Linux
@@ -2032,6 +2049,18 @@ get_queues_for_rss_engine(self) -> dict[str, list[str]]
20322049
get_netq_defq_rss_queues(self, netq_rss: bool) -> list
20332050
```
20342051

2052+
[Linux] Set RSS queues count.
2053+
2054+
```python
2055+
set_rss_queues_count(self, count: int, vf_pci_address: PCIAddress | None = None) -> None
2056+
```
2057+
2058+
[Linux] Get RSS queues count.
2059+
2060+
```python
2061+
get_rss_queues_count(self, vf_pci_address: PCIAddress | None = None) -> int
2062+
```
2063+
20352064
#### Stats
20362065

20372066

@@ -2258,6 +2287,7 @@ Virtualization related functionalities.
22582287
- `set_link_for_vf(vf_id: int, link_state: LinkState) -> None` - Set link for a VF interface.
22592288
- `set_vlan_for_vf(vf_id: int, vlan_id: int, proto: VlanProto) -> None` - Set port VLAN for a VF interface
22602289
- `set_mac_for_vf(vf_id: int, mac: MACAddress) -> None` - Set MAC address for VF interface.
2290+
- `get_vf_id_by_pci(vf_pci_address: PCIAddress) -> int` - Get VF ID based on PCI Address.
22612291
- `get_max_vfs() -> int` - Get maximal number of VFs per interface based on either name or PCI Address (if name not set on the interface).
22622292
- `get_current_vfs() -> int` - Get current number of VFs per interface based on either name or PCI Address (if name not set on the interface).
22632293
- `get_designed_number_vfs() -> tuple[int, int]` - Get designed max number of VFs, total and per PF.

mfd_network_adapter/exceptions.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,19 @@ class NetworkInterfaceIncomparableObject(Exception):
1717

1818
class VirtualFunctionCreationException(Exception):
1919
"""Exception raised when VF creation process fails."""
20+
21+
22+
class VirtualFunctionNotFoundException(Exception):
23+
"""Exception raised when VF is not found after creation."""
24+
25+
26+
class HypervisorNotSupportedException(Exception):
27+
"""Exception raised when the hypervisor is not supported."""
28+
29+
30+
class NetworkAdapterConfigurationException(Exception):
31+
"""Exception raised for errors in network adapter configuration."""
32+
33+
34+
class NetworkInterfaceNotSupported(Exception):
35+
"""Exception raised when the operation called on network interface is not supported."""

mfd_network_adapter/network_adapter_owner/feature/ip/linux.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,27 @@
1818
class LinuxIP(BaseIPFeature):
1919
"""Linux class for IP feature."""
2020

21-
def create_bridge(self, bridge_name: str, namespace: Optional[str] = None) -> None:
21+
def create_bridge(
22+
self, bridge_name: str, additional_parameters: str | None = None, namespace: str | None = None
23+
) -> None:
2224
"""
2325
Create bridge.
2426
2527
:param bridge_name: Bridge name.
28+
:param additional_parameters: Additional parameters for bridge creation.
2629
:param namespace: Name of network namespace
2730
"""
2831
self._connection.execute_command(
29-
add_namespace_call_command(f"ip link add name {bridge_name} type bridge", namespace=namespace)
32+
add_namespace_call_command(
33+
f"ip link add name {bridge_name} type bridge"
34+
f"{' ' + additional_parameters if additional_parameters else ''}",
35+
namespace=namespace,
36+
)
3037
)
3138

32-
def delete_bridge(self, bridge_name: str, namespace: Optional[str] = None) -> None:
39+
def delete_bridge(self, bridge_name: str, namespace: str | None = None) -> None:
3340
"""
34-
Create bridge.
41+
Delete bridge.
3542
3643
:param bridge_name: Bridge name.
3744
:param namespace: Name of network namespace
@@ -60,7 +67,7 @@ def create_namespace(self, namespace_name: str) -> None:
6067
"""
6168
self._connection.execute_command(f"ip netns add {namespace_name}")
6269

63-
def add_to_namespace(self, namespace_name: str, interface_name: str, namespace: Optional[str] = None) -> None:
70+
def add_to_namespace(self, namespace_name: str, interface_name: str, namespace: str | None = None) -> None:
6471
"""
6572
Add interface to namespace.
6673
@@ -80,7 +87,7 @@ def delete_namespace(self, namespace_name: str) -> None:
8087
"""
8188
self._connection.execute_command(f"ip netns delete {namespace_name}")
8289

83-
def add_virtual_link(self, device_name: str, device_type: str, namespace: Optional[str] = None) -> None:
90+
def add_virtual_link(self, device_name: str, device_type: str, namespace: str | None = None) -> None:
8491
"""
8592
Add device/interface with given device type.
8693
@@ -93,7 +100,7 @@ def add_virtual_link(self, device_name: str, device_type: str, namespace: Option
93100
add_namespace_call_command(f"ip link add dev {device_name} type {device_type}", namespace=namespace)
94101
)
95102

96-
def create_veth_interface(self, interface_name: str, peer_name: str, namespace: Optional[str] = None) -> None:
103+
def create_veth_interface(self, interface_name: str, peer_name: str, namespace: str | None = None) -> None:
97104
"""
98105
Create Virtual Ethernet Interface.
99106
@@ -118,7 +125,7 @@ def kill_namespace_processes(self, namespace: str) -> None:
118125
"""
119126
self._connection.execute_command(f"ip netns pids {namespace} | xargs kill", shell=True)
120127

121-
def delete_virtual_link(self, device_name: str, namespace: Optional[str] = None) -> None:
128+
def delete_virtual_link(self, device_name: str, namespace: str | None = None) -> None:
122129
"""
123130
Delete device/interface.
124131

mfd_network_adapter/network_interface/feature/driver/linux.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@
22
# SPDX-License-Identifier: MIT
33
"""Module for Driver feature for Linux."""
44

5+
import logging
56
import re
67
from typing import Dict, TYPE_CHECKING
78

9+
from mfd_common_libs import add_logging_level, log_levels
810
from mfd_const import Speed
911
from mfd_ethtool import Ethtool
12+
from mfd_typing.network_interface import InterfaceType
1013

14+
from mfd_network_adapter.exceptions import NetworkInterfaceNotSupported, NetworkAdapterConfigurationException
1115
from .base import BaseFeatureDriver
1216
from ...exceptions import DriverInfoNotFound
1317

@@ -16,6 +20,9 @@
1620
from mfd_network_adapter import NetworkInterface
1721
from mfd_typing.driver_info import DriverInfo
1822

23+
logger = logging.getLogger(__name__)
24+
add_logging_level(level_name="MODULE_DEBUG", level_value=log_levels.MODULE_DEBUG)
25+
1926

2027
class LinuxDriver(BaseFeatureDriver):
2128
"""Linux class for Driver feature."""
@@ -67,3 +74,28 @@ def get_formatted_driver_version(self) -> Dict:
6774

6875
return ver_dict
6976
raise DriverInfoNotFound(f"Driver version not available for {self._interface().name}")
77+
78+
def set_sriov_drivers_autoprobe(self, state: bool) -> None:
79+
"""
80+
Enable or disable SRIOV drivers auto probe.
81+
82+
:param state: State to set (True or False)
83+
"""
84+
interface = self._interface()
85+
if interface.interface_type is not InterfaceType.PF:
86+
raise NetworkInterfaceNotSupported(
87+
"Enabling/disabling SRIOV drivers auto probe is only supported on PF interface."
88+
)
89+
status = "enabled" if state else "disabled"
90+
logger.log(
91+
level=log_levels.MFD_DEBUG,
92+
msg=f"{status} sriov_drivers_autoprobe on interface {interface.name}",
93+
)
94+
self._connection.execute_command(
95+
f"echo {int(state)} > /sys/class/net/{interface.name}/device/sriov_drivers_autoprobe",
96+
custom_exception=NetworkAdapterConfigurationException,
97+
)
98+
logger.log(
99+
level=log_levels.MFD_INFO,
100+
msg=f"Successfully {status} sriov_drivers_autoprobe on interface {interface.name}",
101+
)

mfd_network_adapter/network_interface/feature/rss/linux.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@
1010
from mfd_common_libs import add_logging_level, log_levels
1111
from mfd_ethtool import Ethtool
1212
from mfd_ethtool.exceptions import EthtoolExecutionError
13+
from mfd_typing import PCIAddress
14+
from mfd_typing.network_interface import InterfaceType
15+
1316
from mfd_network_adapter.data_structures import State
17+
from mfd_network_adapter.exceptions import NetworkInterfaceNotSupported, NetworkAdapterConfigurationException
1418
from mfd_network_adapter.stat_checker.base import Trend
1519

1620
from .base import BaseFeatureRSS
@@ -285,3 +289,54 @@ def validate_statistics(self, traffic_duration: int = 30) -> None:
285289
# in ethtool then get_stats will throw a RuntimeError. That is expected behavior.
286290
# If it does exist, it should be zero.
287291
logger.log(level=log_levels.MODULE_DEBUG, msg=f"Not found {stat_name} statistic, it's expected.")
292+
293+
def set_rss_queues_count(self, count: int, vf_pci_address: PCIAddress | None = None) -> None:
294+
"""
295+
Set number of RSS queues for the given interface.
296+
297+
:param vf_pci_address: PCI address of VF to set RSS queues count for. If not provided, sets for PF.
298+
:param count: Number of RSS queues to set
299+
"""
300+
interface = self._interface()
301+
if interface.interface_type is not InterfaceType.PF:
302+
raise NetworkInterfaceNotSupported("Setting RSS queues count on VF is only supported through PF interface.")
303+
logger.log(
304+
level=log_levels.MFD_DEBUG,
305+
msg=f"Setting RSS queues count to {count} for {'VF' if vf_pci_address else interface.name} interface.",
306+
)
307+
vf_path = ""
308+
if vf_pci_address:
309+
vf_num = str(interface.virtualization.get_vf_id_by_pci(vf_pci_address))
310+
vf_path = f"virtfn{vf_num}/"
311+
self._connection.execute_command(
312+
f"echo {count} > /sys/class/net/{interface.name}/device/{vf_path}rss_lut_pf_attr",
313+
custom_exception=NetworkAdapterConfigurationException,
314+
)
315+
logger.log(
316+
level=log_levels.MFD_INFO,
317+
msg=f"Successfully set RSS queues count on interface {interface.name} to {count}",
318+
)
319+
320+
def get_rss_queues_count(self, vf_pci_address: PCIAddress | None = None) -> int:
321+
"""
322+
Get number of RSS queues of the given interface.
323+
324+
:param vf_pci_address: PCI address of VF to get RSS queues count for. If not provided, gets for PF.
325+
:return: Number of RSS queues
326+
"""
327+
interface = self._interface()
328+
if interface.interface_type is not InterfaceType.PF:
329+
raise NetworkInterfaceNotSupported("Getting RSS queues count on VF is only supported through PF interface.")
330+
logger.log(
331+
level=log_levels.MFD_DEBUG,
332+
msg=f"Retrieving RSS queues count of {'VF' if vf_pci_address else interface.name} interface.",
333+
)
334+
vf_path = ""
335+
if vf_pci_address:
336+
vf_num = str(interface.virtualization.get_vf_id_by_pci(vf_pci_address))
337+
vf_path = f"virtfn{vf_num}/"
338+
out = self._connection.execute_command(
339+
f"cat /sys/class/net/{interface.name}/device/{vf_path}rss_lut_pf_attr",
340+
expected_return_codes={0},
341+
).stdout
342+
return int(out)

mfd_network_adapter/network_interface/feature/virtualization/data_structures.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,11 @@ class VFInfo:
1313
vf_id: str
1414
pci_address: PCIAddress
1515
owner_world_id: str
16+
17+
18+
@dataclass
19+
class MethodType:
20+
"""Class for method types."""
21+
22+
DEVLINK: str = "devlink"
23+
SYSFS: str = "sysfs"

0 commit comments

Comments
 (0)