Skip to content

Feat/12338 mtu implementation v1 - #60

Open
Davihan11 wants to merge 5 commits into
CESNET:mainfrom
Davihan11:feat/12338-mtu-implementation-v1
Open

Davihan11 wants to merge 5 commits into
CESNET:mainfrom
Davihan11:feat/12338-mtu-implementation-v1

Conversation

@Davihan11

Copy link
Copy Markdown
Collaborator

This pull request introduces a new functional test for verifying jumbo frame (MTU) handling on DPDK interfaces, along with supporting infrastructure and documentation. The changes add a parameterized test that replays various packet capture files (pcaps) with increasing IP lengths to validate Suricata's ability to handle frames up to and beyond the configured MTU. The PR also includes the code to generate these pcaps, updates to the test framework to support single-pass pcap replay, and enhancements to the traffic profile manager. Below are the most important changes:

MTU Functional Test Implementation:

  • Added a new functional test (functional_tests/mtu/) that replays a set of pcaps with different IP lengths (1500, 1501, 7000, 9000, 9001 bytes) to verify correct jumbo frame handling and MTU enforcement in Suricata with DPDK. The test is fully parameterized and uses a test-local Suricata config.

Traffic Profile and PCAP Management:

  • Introduced MtuProfile in assets/trex/traffic_profiles/functional_tests/mtu_profile/profile.py to define the set of MTU test pcaps and manage their replay via TRex.
  • Added the generated pcaps for each test stage (mtu_flow_a_1500_1000p.pcap, mtu_flow_a_1501_1000p.pcap, mtu_flow_a_7000_1000p.pcap, mtu_flow_a_9000_1000p.pcap, mtu_flow_a_9001_1000p.pcap) to the repository.

Enhancements to TRex Traffic Profile Manager:

  • Updated BaseTrexClientManager to support selecting and replaying individual pcaps from a profile, including logic for VLAN-tagged variants, and added the set_pcap method for dynamic pcap selection.
  • Modified traffic replay logic to allow STL mode to run in single-pass mode (bounded by pcap content rather than duration), and improved error handling and documentation for duration requirements in all modes.

Documentation:

  • Expanded the README.md with detailed instructions and explanation of the new MTU functional test, including stage descriptions, usage examples, and notes on test behavior.

Other Minor Updates:

  • Added author attribution for Dávid Hanko in relevant files.

These changes collectively enable robust testing of MTU and jumbo frame support in Suricata with DPDK, provide reusable infrastructure for pcap-driven functional tests, and improve test documentation and maintainability.

- TrexTestRun: optional pcap argument restricting TRex traffic to a
  single profile pcap (set_pcap on BaseTrexClientManager)
- STF profile is rebuilt and re-uploaded when the pcap changes
- add generated MTU test pcaps (flow A at IP length 1500/1501/7000/
  9000/9001, 1000 packets each) as LFS objects
TRex infrastructure for functional tests that need exact packet
counts per replayed pcap:

* TrexTestRun.execute(pcap=, single_pass=) - select the pcap and
  optionally disable the duration fallback per execution, so the
  traffic volume is bounded by the pcap content, not by time
* set_props accepts duration=None -> STL single-pass: every pcap is
  transmitted exactly once instead of looping for a duration;
  ASTF and STF still require a duration (explicit guards)
* _selectable_pcaps snapshot taken at the end of __init__ so that
  set_pcap can re-select any profile pcap later, not just the ones
  remaining after the previous narrowing-down
suricata_conf_file now falls back to a suricata.yaml placed next to
the test file when no --suricata-cfg is given, letting a test pin
capture-specific settings (e.g. DPDK queue/RSS config) without a
dedicated command-line path.
Verify jumbo frame handling on a DPDK interface with MTU 9000
(functional_tests/mtu/). The test is parametrized by stage so each
stage is a separate pytest node and runs in isolation:

* stage 1 (IP len 1500): baseline, standard frames received whole
* stage 2 (IP len 1501): off-by-one above the standard MTU
* stage 3 (IP len 7000): mid-range jumbo, exposes undersized buffers
* stage 4 (IP len 9000): exactly the configured MTU boundary
* stage 5 (IP len 9001): one byte above the MTU - frames must be
  rejected

Delivery is asserted on decoder counters from eve-stats (pkts and
ethernet frame counts; bytes as the full L2 frame length, no CRC -
GET_PKT_LEN semantics). Uses a test-local suricata.yaml (mtu 9000
forcing ~9216-byte mbufs, 4 RX queues, interrupt-mode off) and the
new MtuProfile (STL, all 5 pcaps at weight 1). The test forces
dpdk.interfaces[0].mtu to 9000 regardless of the parametrized
value.
Recreates all five MTU test pcaps (flow A at IP length 1500/1501/
7000/9000/9001, 1000 packets each) from scapy - update STAGES and
re-run when the test stages change.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new single_pass path can propagate duration=None through runner hooks whose contract is still typed/structured as int, and the newly added test_settings.json is empty (invalid JSON).

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR adds an MTU/jumbo-frame focused functional test that replays MTU-sized pcaps against Suricata+DPDK via TRex, and extends the TRex traffic profile manager/test runner to support selecting a single pcap and doing STL “single-pass” replays.

Changes:

  • Added a new parameterized MTU functional test (functional_tests/mtu/) plus a test-local Suricata config and a pcap generator script.
  • Extended the TRex profile manager to (a) select a single pcap from a profile and (b) support STL replay bounded by pcap content (duration=None).
  • Updated the runner and docs to allow choosing a pcap per run and documenting the MTU test workflow.
File summaries
File Description
util/test_runner.py Adds pcap selection + single_pass support to the runner API (but needs contract/typing fixes).
README.md Documents the new MTU functional test and how to run individual stages.
conftest.py Allows using a per-test suricata.yaml when present in the test directory.
functional_tests/mtu/test_mtu.py Implements the parameterized MTU test stages and assertions based on eve-stats.json.
functional_tests/mtu/test_settings.json New settings file (currently empty/invalid JSON).
functional_tests/mtu/suricata.yaml Test-local Suricata configuration tailored for MTU=9000 DPDK capture.
functional_tests/mtu/generate_pcaps.py Script to generate the MTU-stage pcaps.
assets/trex/traffic_profiles/trex_client_manager.py Adds set_pcap() and STL single-pass replay (duration=None) support.
assets/trex/traffic_profiles/functional_tests/mtu_profile/profile.py New TRex profile enumerating the MTU-stage pcaps.
assets/trex/traffic_profiles/pcaps/mtu_flow_a_*_1000p.pcap Adds MTU-stage pcap artifacts via Git LFS pointers.
Review details

Suppressed comments (3)

util/test_runner.py:60

  • single_pass=True is documented as explicitly disabling the duration, but if a caller passes duration as well the current logic keeps it. This makes single_pass ineffective and also allows duration=None to flow into the runner without an explicit decision.
        """Run one traffic+stats cycle.

        `duration=None` falls back to `test_info.traffic_duration`; pass
        `single_pass=True` to explicitly disable the duration so the traffic
        is bounded by the pcap content instead of time (each pcap is
        transmitted exactly once).
        """
        if duration is None and not single_pass:
            duration = self.test_info.traffic_duration

        self._before_traffic(multiplier, duration, pcap)

util/test_runner.py:37

  • With single_pass=True, duration can be None, but _run_traffic currently types it as int. Any subclass that uses duration (sleep windows, rate calculations, etc.) could break on None.
    def _run_traffic(self, multiplier: float, duration: int, run_info: RunInfo):
        """Generate traffic. Suricata is already running."""

util/test_runner.py:104

  • TrexTestRun overrides _before_traffic / _run_traffic; their duration annotations should match the base class now that duration=None is valid for STL single-pass runs.
    def _before_traffic(
        self, multiplier: float, duration: int, pcap: str | None = None
    ):
        if pcap is not None:
            self.trex_client.set_pcap(pcap)
        self.trex_client.set_props(multiplier, duration)
        self.trex_client.prepare()

    def _run_traffic(self, multiplier: float, duration: int, run_info: RunInfo):
        # sample TRex's own counters at the measurement-window start
  • Files reviewed: 13/14 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread util/test_runner.py
Comment on lines +31 to +34
def _before_traffic(
self, multiplier: float, duration: int, pcap: str | None = None
):
"""Prepare TRex before suricata starts (select pcap, reset, set_props)."""
Comment on lines +11 to +14
interface MTU). The test is parametrized by stage so a single stage can
be selected and run in isolation via its node ID, e.g.
`functional_tests/mtu/test_mtu.py::test_mtu[2]`:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants