|
37 | 37 | ChecksumOffloadOptions, |
38 | 38 | DeviceCapabilitiesFlag, |
39 | 39 | FlowRule, |
| 40 | + RSSOffloadTypesFlag, |
40 | 41 | RxOffloadCapabilities, |
41 | 42 | RxOffloadCapability, |
42 | 43 | RxOffloadConfiguration, |
@@ -369,6 +370,82 @@ def close_all_ports(self, verify: bool = True) -> None: |
369 | 370 | if not all(f"Port {p_id} is closed" in port_close_output for p_id in range(num_ports)): |
370 | 371 | raise InteractiveCommandExecutionError("Ports were not closed successfully.") |
371 | 372 |
|
| 373 | + def port_config_rss_reta( |
| 374 | + self, port_id: int, hash_index: int, queue_id: int, verify: bool = True |
| 375 | + ) -> None: |
| 376 | + """Configure a port's RSS redirection table. |
| 377 | +
|
| 378 | + Args: |
| 379 | + port_id: The port where the redirection table will be configured. |
| 380 | + hash_index: The index into the redirection table associated with the destination queue. |
| 381 | + queue_id: The destination queue of the packet. |
| 382 | + verify: If :data:`True`, verifies if a port's redirection table |
| 383 | + was correctly configured. |
| 384 | +
|
| 385 | + Raises: |
| 386 | + InteractiveCommandExecutionError: If `verify` is :data:`True` |
| 387 | + Testpmd failed to config RSS reta. |
| 388 | + """ |
| 389 | + out = self.send_command(f"port config {port_id} rss reta ({hash_index},{queue_id})") |
| 390 | + if verify: |
| 391 | + if f"The reta size of port {port_id} is" not in out: |
| 392 | + self._logger.debug(f"Failed to config RSS reta: \n{out}") |
| 393 | + raise InteractiveCommandExecutionError("Testpmd failed to config RSS reta.") |
| 394 | + |
| 395 | + def port_config_all_rss_offload_type( |
| 396 | + self, flag: RSSOffloadTypesFlag, verify: bool = True |
| 397 | + ) -> None: |
| 398 | + """Set the RSS mode on all ports. |
| 399 | +
|
| 400 | + Args: |
| 401 | + flag: The RSS iptype all ports will be configured to. |
| 402 | + verify: If :data:`True`, it verifies if all ports RSS offload type |
| 403 | + was correctly configured. |
| 404 | +
|
| 405 | + Raises: |
| 406 | + InteractiveCommandExecutionError: If `verify` is :data:`True` |
| 407 | + Testpmd failed to config the RSS mode on all ports. |
| 408 | + """ |
| 409 | + out = self.send_command(f"port config all rss {flag.name}") |
| 410 | + if verify: |
| 411 | + if "error" in out: |
| 412 | + self._logger.debug(f"Failed to config the RSS mode on all ports: \n{out}") |
| 413 | + raise InteractiveCommandExecutionError( |
| 414 | + f"Testpmd failed to change RSS mode to {flag.name}" |
| 415 | + ) |
| 416 | + |
| 417 | + def port_config_rss_hash_key( |
| 418 | + self, |
| 419 | + port_id: int, |
| 420 | + offload_type: RSSOffloadTypesFlag, |
| 421 | + hex_str: str, |
| 422 | + verify: bool = True, |
| 423 | + ) -> str: |
| 424 | + """Sets the RSS hash key for the specified port. |
| 425 | +
|
| 426 | + Args: |
| 427 | + port_id: The port that will have the hash key applied to. |
| 428 | + offload_type: The offload type the hash key will be applied to. |
| 429 | + hex_str: The hash key to set. |
| 430 | + verify: If :data:`True`, verify that RSS has the key. |
| 431 | +
|
| 432 | + Raises: |
| 433 | + InteractiveCommandExecutionError: If `verify` is :data:`True` |
| 434 | + Testpmd failed to set the RSS hash key. |
| 435 | + """ |
| 436 | + output = self.send_command( |
| 437 | + f"port config {port_id} rss-hash-key {offload_type} {hex_str}", |
| 438 | + skip_first_line=True, |
| 439 | + ) |
| 440 | + |
| 441 | + if verify: |
| 442 | + if output.strip(): |
| 443 | + self._logger.debug(f"Failed to set rss hash key: \n{output}") |
| 444 | + raise InteractiveCommandExecutionError( |
| 445 | + f"Testpmd failed to set {hex_str} on {port_id} with a flag of {offload_type}." |
| 446 | + ) |
| 447 | + return output |
| 448 | + |
372 | 449 | def show_port_info_all(self) -> list[TestPmdPort]: |
373 | 450 | """Returns the information of all the ports. |
374 | 451 |
|
@@ -587,22 +664,30 @@ def csum_set_hw( |
587 | 664 | {port_id}:\n{csum_output}""" |
588 | 665 | ) |
589 | 666 |
|
590 | | - def flow_create(self, flow_rule: FlowRule, port_id: int) -> int: |
| 667 | + def flow_create(self, flow_rule: FlowRule, port_id: int, verify: bool = True) -> int: |
591 | 668 | """Creates a flow rule in the testpmd session. |
592 | 669 |
|
593 | 670 | This command is implicitly verified as needed to return the created flow rule id. |
594 | 671 |
|
595 | 672 | Args: |
596 | 673 | flow_rule: :class:`FlowRule` object used for creating testpmd flow rule. |
597 | 674 | port_id: Integer representing the port to use. |
| 675 | + verify: If :data:`True`, the output of the command is scanned |
| 676 | + to ensure the flow rule was created successfully. |
598 | 677 |
|
599 | 678 | Raises: |
600 | 679 | InteractiveCommandExecutionError: If flow rule is invalid. |
601 | 680 |
|
602 | 681 | Returns: |
603 | | - Id of created flow rule. |
| 682 | + Id of created flow rule as an integer. |
604 | 683 | """ |
605 | 684 | flow_output = self.send_command(f"flow create {port_id} {flow_rule}") |
| 685 | + if verify: |
| 686 | + if "created" not in flow_output: |
| 687 | + self._logger.debug(f"Failed to create flow rule:\n{flow_output}") |
| 688 | + raise InteractiveCommandExecutionError( |
| 689 | + f"Failed to create flow rule:\n{flow_output}" |
| 690 | + ) |
606 | 691 | match = re.search(r"#(\d+)", flow_output) |
607 | 692 | if match is not None: |
608 | 693 | match_str = match.group(1) |
@@ -631,7 +716,7 @@ def flow_delete(self, flow_id: int, port_id: int, verify: bool = True) -> None: |
631 | 716 | """Deletes the specified flow rule from the testpmd session. |
632 | 717 |
|
633 | 718 | Args: |
634 | | - flow_id: ID of the flow to remove. |
| 719 | + flow_id: :class:`FlowRule` id used for deleting testpmd flow rule. |
635 | 720 | port_id: Integer representing the port to use. |
636 | 721 | verify: If :data:`True`, the output of the command is scanned |
637 | 722 | to ensure the flow rule was deleted successfully. |
|
0 commit comments