diff --git a/ansible_collections/arista/avd/molecule/eos_cli_config_gen/documentation/devices/host1.md b/ansible_collections/arista/avd/molecule/eos_cli_config_gen/documentation/devices/host1.md index dd07ba11572..d404a2c128d 100644 --- a/ansible_collections/arista/avd/molecule/eos_cli_config_gen/documentation/devices/host1.md +++ b/ansible_collections/arista/avd/molecule/eos_cli_config_gen/documentation/devices/host1.md @@ -10700,6 +10700,27 @@ ipv6 address virtual source-nat vrf TEST_04 address 2001:db8:85a3::8a2e:370:7335 | Settings | Value | | -------- | ----- | | Maximum CPU Allocation | 42 | +| Interface profile | TestProfile1 | + +#### Platform Software Forwarding Engine Interface Profiles + +##### TestProfile1 + +| Interface | Rx-Queue Count | Rx-Queue Worker | Rx-Queue Mode | +| --------- | -------------- | --------------- | ------------- | +| Ethernet1/1 | 4 | 0-2,5 | - | +| Ethernet1/2 | 2 | - | shared | +| Ethernet1/4 | 1 | - | - | +| Ethernet1/5 | 2 | 3,4 | exclusive | + +##### TestProfile2 + +| Interface | Rx-Queue Count | Rx-Queue Worker | Rx-Queue Mode | +| --------- | -------------- | --------------- | ------------- | +| Ethernet1 | 3 | 2 | - | +| Ethernet9 | - | - | - | + +##### TestProfile3 ### Platform Device Configuration @@ -10716,6 +10737,35 @@ platform sand qos map traffic-class 2 to network-qos 15 platform sand multicast replication default ingress platform sand mdb profile l3-xxl platform sfe data-plane cpu allocation maximum 42 +! +platform sfe interface + interface profile TestProfile1 + ! + profile TestProfile1 + interface Ethernet1/1 + rx-queue count 4 + rx-queue worker 0-2,5 + ! + interface Ethernet1/2 + rx-queue count 2 + rx-queue mode shared + ! + interface Ethernet1/4 + rx-queue count 1 + ! + interface Ethernet1/5 + rx-queue count 2 + rx-queue worker 3,4 + rx-queue mode exclusive + ! + profile TestProfile2 + interface Ethernet1 + rx-queue count 3 + rx-queue worker 2 + ! + interface Ethernet9 + ! + profile TestProfile3 ``` ## System L1 diff --git a/ansible_collections/arista/avd/molecule/eos_cli_config_gen/intended/configs/host1.cfg b/ansible_collections/arista/avd/molecule/eos_cli_config_gen/intended/configs/host1.cfg index a02cbd427f4..d985bd9eb04 100644 --- a/ansible_collections/arista/avd/molecule/eos_cli_config_gen/intended/configs/host1.cfg +++ b/ansible_collections/arista/avd/molecule/eos_cli_config_gen/intended/configs/host1.cfg @@ -284,6 +284,35 @@ logging event congestion-drops interval 10 ! load-interval default 25 ! +platform sfe interface + interface profile TestProfile1 + ! + profile TestProfile1 + interface Ethernet1/1 + rx-queue count 4 + rx-queue worker 0-2,5 + ! + interface Ethernet1/2 + rx-queue count 2 + rx-queue mode shared + ! + interface Ethernet1/4 + rx-queue count 1 + ! + interface Ethernet1/5 + rx-queue count 2 + rx-queue worker 3,4 + rx-queue mode exclusive + ! + profile TestProfile2 + interface Ethernet1 + rx-queue count 3 + rx-queue worker 2 + ! + interface Ethernet9 + ! + profile TestProfile3 +! interface defaults mtu 9000 ethernet diff --git a/ansible_collections/arista/avd/molecule/eos_cli_config_gen/inventory/host_vars/host1/platform.yml b/ansible_collections/arista/avd/molecule/eos_cli_config_gen/inventory/host_vars/host1/platform.yml index 475a25278cd..7260fd4d726 100644 --- a/ansible_collections/arista/avd/molecule/eos_cli_config_gen/inventory/host_vars/host1/platform.yml +++ b/ansible_collections/arista/avd/molecule/eos_cli_config_gen/inventory/host_vars/host1/platform.yml @@ -71,3 +71,32 @@ platform: mdb_profile: "l3-xxl" sfe: data_plane_cpu_allocation_max: 42 + interface: + profiles: + - name: TestProfile1 + interfaces: + - name: Ethernet1/1 + rx_queue: + count: 4 + worker: "0-2,5" + - name: Ethernet1/5 + rx_queue: + count: 2 + worker: "3,4" + mode: exclusive + - name: Ethernet1/2 + rx_queue: + count: 2 + mode: shared + - name: Ethernet1/4 + rx_queue: + count: 1 + - name: TestProfile2 + interfaces: + - name: Ethernet1 + rx_queue: + count: 3 + worker: "2" + - name: Ethernet9 + - name: TestProfile3 + interface_profile: TestProfile1 diff --git a/ansible_collections/arista/avd/roles/eos_cli_config_gen/docs/tables/platform.md b/ansible_collections/arista/avd/roles/eos_cli_config_gen/docs/tables/platform.md index 4433f5b4732..b4b3697c658 100644 --- a/ansible_collections/arista/avd/roles/eos_cli_config_gen/docs/tables/platform.md +++ b/ansible_collections/arista/avd/roles/eos_cli_config_gen/docs/tables/platform.md @@ -45,6 +45,16 @@ | [    mdb_profile](## "platform.sand.mdb_profile") | String | | | Valid Values:
- balanced
- balanced-xl
- l3
- l3-xl
- l3-xxl
- l3-xxxl | Sand platforms MDB Profile configuration. Note: l3-xxxl does not support MLAG. | | [  sfe](## "platform.sfe") | Dictionary | | | | Sfe (Software Forwarding Engine) settings. | | [    data_plane_cpu_allocation_max](## "platform.sfe.data_plane_cpu_allocation_max") | Integer | | | Min: 1
Max: 128 | Maximum number of CPUs used for data plane traffic forwarding. | + | [    interface](## "platform.sfe.interface") | Dictionary | | | | Configure interface related settings for Sfe platform. | + | [      profiles](## "platform.sfe.interface.profiles") | List, items: Dictionary | | | | Configure one or more Receive Side Scaling (RSS) interface profiles.
This is supported on specific platforms. | + | [        - name](## "platform.sfe.interface.profiles.[].name") | String | Required, Unique | | | RSS interface profile name. | + | [          interfaces](## "platform.sfe.interface.profiles.[].interfaces") | List, items: Dictionary | | | | Interfaces within RSS profile. | + | [            - name](## "platform.sfe.interface.profiles.[].interfaces.[].name") | String | Required, Unique | | | Interface name such as 'Ethernet2'. | + | [              rx_queue](## "platform.sfe.interface.profiles.[].interfaces.[].rx_queue") | Dictionary | | | | Receive queue parameters for the selected interface. | + | [                count](## "platform.sfe.interface.profiles.[].interfaces.[].rx_queue.count") | Integer | | | Min: 1 | Number of receive queues.
The maximum value is platform dependent. | + | [                worker](## "platform.sfe.interface.profiles.[].interfaces.[].rx_queue.worker") | String | | | | Worker ids specified as combination of range and/or comma separated values
such as 0-4,7. | + | [                mode](## "platform.sfe.interface.profiles.[].interfaces.[].rx_queue.mode") | String | | | Valid Values:
- shared
- exclusive | Mode applicable to the workers. Default mode is 'shared'. | + | [      interface_profile](## "platform.sfe.interface.interface_profile") | String | | | | RSS interface profile name to apply for the platform.
Needs system reload or Sfe agent restart for change to take effect. | === "YAML" @@ -122,4 +132,38 @@ # Maximum number of CPUs used for data plane traffic forwarding. data_plane_cpu_allocation_max: + + # Configure interface related settings for Sfe platform. + interface: + + # Configure one or more Receive Side Scaling (RSS) interface profiles. + # This is supported on specific platforms. + profiles: + + # RSS interface profile name. + - name: + + # Interfaces within RSS profile. + interfaces: + + # Interface name such as 'Ethernet2'. + - name: + + # Receive queue parameters for the selected interface. + rx_queue: + + # Number of receive queues. + # The maximum value is platform dependent. + count: =1> + + # Worker ids specified as combination of range and/or comma separated values + # such as 0-4,7. + worker: + + # Mode applicable to the workers. Default mode is 'shared'. + mode: + + # RSS interface profile name to apply for the platform. + # Needs system reload or Sfe agent restart for change to take effect. + interface_profile: ``` diff --git a/python-avd/pyavd/_eos_cli_config_gen/j2templates/documentation/platform.j2 b/python-avd/pyavd/_eos_cli_config_gen/j2templates/documentation/platform.j2 index de54be0c6ac..e4e848ec876 100644 --- a/python-avd/pyavd/_eos_cli_config_gen/j2templates/documentation/platform.j2 +++ b/python-avd/pyavd/_eos_cli_config_gen/j2templates/documentation/platform.j2 @@ -83,6 +83,31 @@ {% if platform.sfe.data_plane_cpu_allocation_max is arista.avd.defined %} | Maximum CPU Allocation | {{ platform.sfe.data_plane_cpu_allocation_max }} | {% endif %} +{## Platform Sfe Interface #} +{% if platform.sfe.interface is arista.avd.defined %} +{% if platform.sfe.interface.interface_profile is arista.avd.defined %} +| Interface profile | {{ platform.sfe.interface.interface_profile }} | +{% endif %} +{% if platform.sfe.interface.profiles is arista.avd.defined %} + +#### Platform Software Forwarding Engine Interface Profiles +{% for profile_data in platform.sfe.interface.profiles | arista.avd.natural_sort('name') %} + +##### {{ profile_data.name }} +{% if profile_data.interfaces is arista.avd.defined %} + +| Interface | Rx-Queue Count | Rx-Queue Worker | Rx-Queue Mode | +| --------- | -------------- | --------------- | ------------- | +{% for interface_data in profile_data.interfaces | arista.avd.natural_sort('name') %} +{% set rx_queue_count = interface_data.rx_queue.count | arista.avd.default('-') %} +{% set rx_queue_worker = interface_data.rx_queue.worker | arista.avd.default('-') %} +{% set rx_queue_mode = interface_data.rx_queue.mode | arista.avd.default('-') %} +| {{ interface_data.name }} | {{ rx_queue_count }} | {{ rx_queue_worker }} | {{ rx_queue_mode }} | +{% endfor %} +{% endif %} +{% endfor %} +{% endif %} +{% endif %} {% endif %} {% endif %} @@ -90,5 +115,6 @@ ```eos {% include 'eos/platform.j2' %} +{% include 'eos/platform-sfe-interface.j2' %} ``` {% endif %} diff --git a/python-avd/pyavd/_eos_cli_config_gen/j2templates/eos-intended-config.j2 b/python-avd/pyavd/_eos_cli_config_gen/j2templates/eos-intended-config.j2 index 9c6be0d49d0..74b677d1803 100644 --- a/python-avd/pyavd/_eos_cli_config_gen/j2templates/eos-intended-config.j2 +++ b/python-avd/pyavd/_eos_cli_config_gen/j2templates/eos-intended-config.j2 @@ -64,6 +64,8 @@ {% include 'eos/load-interval.j2' %} {# transceiver qsfp default mode #} {% include 'eos/transceiver-qsfp-default-mode.j2' %} +{# platform sfe interface #} +{% include 'eos/platform-sfe-interface.j2' %} {# interface defaults #} {% include 'eos/interface-defaults.j2' %} {# service routing protocols model #} diff --git a/python-avd/pyavd/_eos_cli_config_gen/j2templates/eos/platform-sfe-interface.j2 b/python-avd/pyavd/_eos_cli_config_gen/j2templates/eos/platform-sfe-interface.j2 new file mode 100644 index 00000000000..2504c405ae2 --- /dev/null +++ b/python-avd/pyavd/_eos_cli_config_gen/j2templates/eos/platform-sfe-interface.j2 @@ -0,0 +1,34 @@ +{# + Copyright (c) 2023-2025 Arista Networks, Inc. + Use of this source code is governed by the Apache License 2.0 + that can be found in the LICENSE file. +#} +{# eos - platform sfe interface #} +{% if platform.sfe.interface is arista.avd.defined %} +! +platform sfe interface +{# interface profile to apply #} +{% if platform.sfe.interface.interface_profile is arista.avd.defined %} + interface profile {{ platform.sfe.interface.interface_profile }} +{% endif %} +{% for profile_data in platform.sfe.interface.profiles | arista.avd.natural_sort('name') %} +{# profiles available #} + ! + profile {{ profile_data.name }} +{% for interface_data in profile_data.interfaces | arista.avd.natural_sort('name') %} + interface {{ interface_data.name }} +{% if interface_data.rx_queue.count is arista.avd.defined %} + rx-queue count {{ interface_data.rx_queue.count }} +{% endif %} +{% if interface_data.rx_queue.worker is arista.avd.defined %} + rx-queue worker {{ interface_data.rx_queue.worker }} +{% endif %} +{% if interface_data.rx_queue.mode is arista.avd.defined %} + rx-queue mode {{ interface_data.rx_queue.mode }} +{% endif %} +{% if not loop.last %} + ! +{% endif %} +{% endfor %} +{% endfor %} +{% endif %} diff --git a/python-avd/pyavd/_eos_cli_config_gen/schema/__init__.py b/python-avd/pyavd/_eos_cli_config_gen/schema/__init__.py index 0a4fc19cb1d..928e88db9d3 100644 --- a/python-avd/pyavd/_eos_cli_config_gen/schema/__init__.py +++ b/python-avd/pyavd/_eos_cli_config_gen/schema/__init__.py @@ -24826,13 +24826,184 @@ def __init__( class Sfe(AvdModel): """Subclass of AvdModel.""" - _fields: ClassVar[dict] = {"data_plane_cpu_allocation_max": {"type": int}} + class Interface(AvdModel): + """Subclass of AvdModel.""" + + class ProfilesItem(AvdModel): + """Subclass of AvdModel.""" + + class InterfacesItem(AvdModel): + """Subclass of AvdModel.""" + + class RxQueue(AvdModel): + """Subclass of AvdModel.""" + + _fields: ClassVar[dict] = {"count": {"type": int}, "worker": {"type": str}, "mode": {"type": str}} + count: int | None + """ + Number of receive queues. + The maximum value is platform dependent. + """ + worker: str | None + """ + Worker ids specified as combination of range and/or comma separated values + such as 0-4,7. + """ + mode: Literal["shared", "exclusive"] | None + """Mode applicable to the workers. Default mode is 'shared'.""" + + if TYPE_CHECKING: + + def __init__( + self, + *, + count: int | None | UndefinedType = Undefined, + worker: str | None | UndefinedType = Undefined, + mode: Literal["shared", "exclusive"] | None | UndefinedType = Undefined, + ) -> None: + """ + RxQueue. + + + Subclass of AvdModel. + + Args: + count: + Number of receive queues. + The maximum value is platform dependent. + worker: + Worker ids specified as combination of range and/or comma separated values + such as 0-4,7. + mode: Mode applicable to the workers. Default mode is 'shared'. + + """ + + _fields: ClassVar[dict] = {"name": {"type": str}, "rx_queue": {"type": RxQueue}} + name: str + """Interface name such as 'Ethernet2'.""" + rx_queue: RxQueue + """ + Receive queue parameters for the selected interface. + + Subclass of AvdModel. + """ + + if TYPE_CHECKING: + + def __init__(self, *, name: str | UndefinedType = Undefined, rx_queue: RxQueue | UndefinedType = Undefined) -> None: + """ + InterfacesItem. + + + Subclass of AvdModel. + + Args: + name: Interface name such as 'Ethernet2'. + rx_queue: + Receive queue parameters for the selected interface. + + Subclass of AvdModel. + + """ + + class Interfaces(AvdIndexedList[str, InterfacesItem]): + """Subclass of AvdIndexedList with `InterfacesItem` items. Primary key is `name` (`str`).""" + + _primary_key: ClassVar[str] = "name" + + Interfaces._item_type = InterfacesItem + + _fields: ClassVar[dict] = {"name": {"type": str}, "interfaces": {"type": Interfaces}} + name: str + """RSS interface profile name.""" + interfaces: Interfaces + """ + Interfaces within RSS profile. + + Subclass of AvdIndexedList with `InterfacesItem` items. Primary key + is `name` (`str`). + """ + + if TYPE_CHECKING: + + def __init__(self, *, name: str | UndefinedType = Undefined, interfaces: Interfaces | UndefinedType = Undefined) -> None: + """ + ProfilesItem. + + + Subclass of AvdModel. + + Args: + name: RSS interface profile name. + interfaces: + Interfaces within RSS profile. + + Subclass of AvdIndexedList with `InterfacesItem` items. Primary key + is `name` (`str`). + + """ + + class Profiles(AvdIndexedList[str, ProfilesItem]): + """Subclass of AvdIndexedList with `ProfilesItem` items. Primary key is `name` (`str`).""" + + _primary_key: ClassVar[str] = "name" + + Profiles._item_type = ProfilesItem + + _fields: ClassVar[dict] = {"profiles": {"type": Profiles}, "interface_profile": {"type": str}} + profiles: Profiles + """ + Configure one or more Receive Side Scaling (RSS) interface profiles. + This is supported on specific + platforms. + + Subclass of AvdIndexedList with `ProfilesItem` items. Primary key is `name` (`str`). + """ + interface_profile: str | None + """ + RSS interface profile name to apply for the platform. + Needs system reload or Sfe agent restart for + change to take effect. + """ + + if TYPE_CHECKING: + + def __init__(self, *, profiles: Profiles | UndefinedType = Undefined, interface_profile: str | None | UndefinedType = Undefined) -> None: + """ + Interface. + + + Subclass of AvdModel. + + Args: + profiles: + Configure one or more Receive Side Scaling (RSS) interface profiles. + This is supported on specific + platforms. + + Subclass of AvdIndexedList with `ProfilesItem` items. Primary key is `name` (`str`). + interface_profile: + RSS interface profile name to apply for the platform. + Needs system reload or Sfe agent restart for + change to take effect. + + """ + + _fields: ClassVar[dict] = {"data_plane_cpu_allocation_max": {"type": int}, "interface": {"type": Interface}} data_plane_cpu_allocation_max: int | None """Maximum number of CPUs used for data plane traffic forwarding.""" + interface: Interface + """ + Configure interface related settings for Sfe platform. + + Subclass of AvdModel. + """ if TYPE_CHECKING: - def __init__(self, *, data_plane_cpu_allocation_max: int | None | UndefinedType = Undefined) -> None: + def __init__( + self, *, data_plane_cpu_allocation_max: int | None | UndefinedType = Undefined, interface: Interface | UndefinedType = Undefined + ) -> None: """ Sfe. @@ -24841,6 +25012,10 @@ def __init__(self, *, data_plane_cpu_allocation_max: int | None | UndefinedType Args: data_plane_cpu_allocation_max: Maximum number of CPUs used for data plane traffic forwarding. + interface: + Configure interface related settings for Sfe platform. + + Subclass of AvdModel. """ diff --git a/python-avd/pyavd/_eos_cli_config_gen/schema/eos_cli_config_gen.schema.yml b/python-avd/pyavd/_eos_cli_config_gen/schema/eos_cli_config_gen.schema.yml index 2084b7a1afd..3d1b9a9b202 100644 --- a/python-avd/pyavd/_eos_cli_config_gen/schema/eos_cli_config_gen.schema.yml +++ b/python-avd/pyavd/_eos_cli_config_gen/schema/eos_cli_config_gen.schema.yml @@ -9830,6 +9830,64 @@ keys: - str min: 1 max: 128 + interface: + type: dict + description: Configure interface related settings for Sfe platform. + keys: + profiles: + type: list + primary_key: name + description: 'Configure one or more Receive Side Scaling (RSS) interface + profiles. + + This is supported on specific platforms.' + items: + type: dict + keys: + name: + type: str + description: RSS interface profile name. + interfaces: + type: list + description: Interfaces within RSS profile. + primary_key: name + items: + type: dict + keys: + name: + type: str + description: Interface name such as 'Ethernet2'. + rx_queue: + type: dict + description: Receive queue parameters for the selected + interface. + keys: + count: + type: int + min: 1 + convert_types: + - str + description: 'Number of receive queues. + + The maximum value is platform dependent.' + worker: + type: str + description: 'Worker ids specified as combination + of range and/or comma separated values + + such as 0-4,7.' + mode: + type: str + description: Mode applicable to the workers. Default + mode is 'shared'. + valid_values: + - shared + - exclusive + interface_profile: + type: str + description: 'RSS interface profile name to apply for the platform. + + Needs system reload or Sfe agent restart for change to take effect.' poe: type: dict keys: diff --git a/python-avd/pyavd/_eos_cli_config_gen/schema/schema_fragments/platform.schema.yml b/python-avd/pyavd/_eos_cli_config_gen/schema/schema_fragments/platform.schema.yml index 5f1152408bb..265229877ae 100644 --- a/python-avd/pyavd/_eos_cli_config_gen/schema/schema_fragments/platform.schema.yml +++ b/python-avd/pyavd/_eos_cli_config_gen/schema/schema_fragments/platform.schema.yml @@ -182,3 +182,58 @@ keys: - str min: 1 max: 128 + interface: + type: dict + description: Configure interface related settings for Sfe platform. + keys: + profiles: + type: list + primary_key: name + description: |- + Configure one or more Receive Side Scaling (RSS) interface profiles. + This is supported on specific platforms. + items: + type: dict + keys: + name: + type: str + description: RSS interface profile name. + interfaces: + type: list + description: Interfaces within RSS profile. + primary_key: name + items: + type: dict + keys: + name: + type: str + description: Interface name such as 'Ethernet2'. + # pattern: "Ethernet[\\d/]+" + rx_queue: + type: dict + description: Receive queue parameters for the selected interface. + keys: + count: + type: int + min: 1 + convert_types: + - str + description: |- + Number of receive queues. + The maximum value is platform dependent. + worker: + type: str + description: |- + Worker ids specified as combination of range and/or comma separated values + such as 0-4,7. + mode: + type: str + description: Mode applicable to the workers. Default mode is 'shared'. + valid_values: + - shared + - exclusive + interface_profile: + type: str + description: |- + RSS interface profile name to apply for the platform. + Needs system reload or Sfe agent restart for change to take effect.