Skip to content

dpdk: stop engine after net_pcap PCAP end of file#14817

Open
mmaatuq wants to merge 1 commit intoOISF:mainfrom
mmaatuq:dpdk-pcap-stop-after-zero-rx-8225
Open

dpdk: stop engine after net_pcap PCAP end of file#14817
mmaatuq wants to merge 1 commit intoOISF:mainfrom
mmaatuq:dpdk-pcap-stop-after-zero-rx-8225

Conversation

@mmaatuq
Copy link
Contributor

@mmaatuq mmaatuq commented Feb 15, 2026

Make sure these boxes are checked accordingly before submitting your Pull Request -- thank you.

Contribution style:

Our Contribution agreements:

Changes (if applicable):

Link to ticket: https://redmine.openinfosecfoundation.org/issues/8225

Describe changes:
When using DPDK's net_pcap PMD to read PCAP files, Suricata previously stayed stuck in the RX loop after the file was fully consumed because no EOF signal exists — only zero packets returned by rte_eth_rx_burst.

Detect the net_pcap driver during device configuration and track active pcap workers with an atomic counter in DPDKWorkerSync. When a worker receives zero packets it decrements the counter; the last worker to finish calls EngineStop to initiate graceful shutdown.

A separate receive loop (ReceiveDPDKLoopPcap) is used for net_pcap interfaces to keep the zero-RX EOF check and atomic decrement off the live capture fast path entirely — the dispatch happens once at loop entry so the live loop (ReceiveDPDKLoopLive) remains unchanged with no additional branches.

The common packet burst processing is extracted into the inline helper ReceiveDPDKPkts shared by both loops.

Ticket: #8225

Provide values to any of the below to override the defaults.

  • To use a Suricata-Verify or Suricata-Update pull request,
    link to the pull request in the respective _BRANCH variable.
  • Leave unused overrides blank or remove.

SV_REPO=
SV_BRANCH=
SU_REPO=
SU_BRANCH=

When using DPDK's net_pcap PMD to read PCAP files, Suricata
previously stayed stuck in the RX loop after the file was fully
consumed because no EOF signal exists — only zero packets returned
by rte_eth_rx_burst.

Detect the net_pcap driver during device configuration and track
active pcap workers with an atomic counter in DPDKWorkerSync. When
a worker receives zero packets it decrements the counter; the last
worker to finish calls EngineStop to initiate graceful shutdown.

A separate receive loop (ReceiveDPDKLoopPcap) is used for net_pcap
interfaces to keep the zero-RX EOF check and atomic decrement off
the live capture fast path entirely — the dispatch happens once at
loop entry so the live loop (ReceiveDPDKLoopLive) remains unchanged
with no additional branches.

The common packet burst processing is extracted into the inline
helper ReceiveDPDKPkts shared by both loops.

Ticket: OISF#8225

Signed-off-by: mmaatuq <[email protected]>
@github-actions
Copy link

NOTE: This PR may contain new authors.

@lukashino
Copy link
Contributor

The PR doesn't work for me with 2+ PCAPs.

e.g., here is the output, but the second port (PCAP) is much larger. Suricata is regardless stopped after the first PCAP is finished processing.

Notice: threads: Threads created -> W: 2 FM: 1 FR: 1   Engine started. [TmThreadWaitOnThreadRunning:tm-threads.c:1960]
Perf: hugepages: Hugepages on NUMA node 0 can be set to 173 (only using 150/989 2048kB hugepages) [SystemHugepageEvaluateHugepages:util-hugepages.c:406]
Perf: hugepages: 2048kB hugepages on NUMA node 1 are unused and can be deallocated [SystemHugepageEvaluateHugepages:util-hugepages.c:391]
Notice: dpdk: net_pcap0: PCAP end of file [ReceiveDPDKLoopPcap:source-dpdk.c:624]
Perf: dpdk: Port 0 (net_pcap0) - rx_good_packets: 4502 [PrintDPDKPortXstats:source-dpdk.c:519]
Perf: dpdk: Port 0 (net_pcap0) - rx_good_bytes: 5370637 [PrintDPDKPortXstats:source-dpdk.c:519]
Perf: dpdk: Port 0 (net_pcap0) - rx_q0_packets: 4502 [PrintDPDKPortXstats:source-dpdk.c:519]
Perf: dpdk: Port 0 (net_pcap0) - rx_q0_bytes: 5370637 [PrintDPDKPortXstats:source-dpdk.c:519]
Perf: dpdk: Port 1 (net_pcap1) - rx_good_packets: 2016 [PrintDPDKPortXstats:source-dpdk.c:519]
Perf: dpdk: Port 1 (net_pcap1) - rx_good_bytes: 1445028 [PrintDPDKPortXstats:source-dpdk.c:519]
Perf: dpdk: Port 1 (net_pcap1) - rx_q0_packets: 2016 [PrintDPDKPortXstats:source-dpdk.c:519]
Perf: dpdk: Port 1 (net_pcap1) - rx_q0_bytes: 1445028 [PrintDPDKPortXstats:source-dpdk.c:519]
Notice: suricata: Signal Received.  Stopping engine. [SuricataMainLoop:suricata.c:2970]
Info: suricata: time elapsed 1.351s [SCPrintElapsedTime:suricata.c:1238]
Perf: flow-manager: 100 flows processed [FlowRecycler:flow-manager.c:1187]
Perf: detect: threshold thread cache stats: cnt:0 notinit:0 nosupport:0 miss_expired:0 miss:0 hit:0, housekeeping: checks:0, expired:0 [DumpCacheStats:detect-engine-threshold.c:410]
Perf: detect: threshold thread cache stats: cnt:0 notinit:0 nosupport:0 miss_expired:0 miss:0 hit:0, housekeeping: checks:0, expired:0 [DumpCacheStats:detect-engine-threshold.c:410]
Info: counters: Alerts: 0 [StatsLogSummary:counters.c:954]
Perf: ippair: ippair memory usage: 398144 bytes, maximum: 16777216 [IPPairPrintStats:ippair.c:284]
Perf: host: host memory usage: 382144 bytes, maximum: 33554432 [HostPrintStats:host.c:290]
Perf: dpdk: net_pcap0: closing device [DPDKCloseDevice:util-dpdk.c:53]
Perf: dpdk: net_pcap1: closing device [DPDKCloseDevice:util-dpdk.c:53]
Notice: device: net_pcap0: packets: 4502, drops: 0 (0.00%), invalid chksum: 0 [LiveDeviceListClean:util-device.c:345]
Notice: device: net_pcap1: packets: 2016, drops: 0 (0.00%), invalid chksum: 0 [LiveDeviceListClean:util-device.c:345]

Here is my example config:

dpdk:
  eal-params:
    proc-type: primary
    no-pci:
    file-prefix: pcaptest
    vdev: ["net_pcap0,rx_pcap=/data/pcap/download_raw.pcap", "net_pcap1,rx_pcap=/data/stratosphere/malware-pcaps/CTU-Mixed-Capture-1/2015-07-28_mixed.pcap"]

So perhaps fixing this and adding extra Github CI/suricata-verify tests wouldn't hurt. The tests should primarily test this functionality (the support of net_pcap driver), that packets and bytes read from multiple PCAPs are as expected.

Copy link
Contributor

@lukashino lukashino left a comment

Choose a reason for hiding this comment

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

In general it looks ok but needs some fixing + tests.

@mmaatuq
Copy link
Contributor Author

mmaatuq commented Feb 21, 2026

    vdev: ["net_pcap0,rx_pcap=/data/pcap/download_raw.pcap", "net_pcap1,rx_pcap=/data/stratosphere/malware-pcaps/CTU-Mixed-Capture-1/2015-07-28_mixed.pcap"]

I did already some tests with multiple pcaps and it was working fine, but now I understand the difference on my tests i was using the same net_pcap name "net_pcap0" and having multiple pcaps was translated to one interface but multiple rx queues, on your test it's multiple interfaces each single rx queue, the synchronization that was implemented is between workers of the same interface. let me handle this.

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

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants