Skip to content

Add DeviceConfiguration::disableImmediateMode to allow TPACKET_V3 on Linux - #2210

Open
MerinoSheep wants to merge 12 commits into
seladb:devfrom
MerinoSheep:feature/disable-immediate-mode
Open

Add DeviceConfiguration::disableImmediateMode to allow TPACKET_V3 on Linux#2210
MerinoSheep wants to merge 12 commits into
seladb:devfrom
MerinoSheep:feature/disable-immediate-mode

Conversation

@MerinoSheep

Copy link
Copy Markdown
Contributor

Summary

  • Addresses HAS_PCAP_IMMEDIATE_MODE for TPACKET_V3 #2206.
  • PcapPlusPlus always enables libpcap's immediate mode where supported, for minimal latency.
  • On Linux this forces the less efficient TPACKET_V2 path instead of TPACKET_V3 (blocking, batched reads), hurting throughput/CPU at high packet rates. This became unconditional in Remove libpcap checks for options available since libpcap >=0.9 #1772 (previously opt-in via PCAPPP_ENABLE_PCAP_IMMEDIATE_MODE, default OFF).
  • Adds DeviceConfiguration::disableImmediateMode (default false, backward compatible) to opt out and let Linux use TPACKET_V3.

Changes

  • PcapLiveDevice.h: new disableImmediateMode field + constructor param (default false).
  • PcapLiveDevice.cpp:
    • doOpen() skips pcap_set_immediate_mode() when set.
    • Falls back to a 100 ms timeout on Linux/Windows when disabled and no packetBufferTimeoutMs is given (their default -1 is unpredictable without immediate mode). FreeBSD/macOS keep their existing pcap_breakloop() workaround timeouts untouched.
  • LiveDeviceTests.cpp: TestPcapLiveDeviceBlockingMode now also runs against a disableImmediateMode = true config.

MerinoSheep and others added 8 commits August 5, 2026 15:36
…Linux

doOpen() unconditionally enables libpcap's immediate mode whenever the
platform supports it, with no way to opt out. On Linux this forces
libpcap to fall back from TPACKET_V3 to TPACKET_V2 and forces a
non-blocking poll_timeout=0, turning the capture loop into a
continuous busy-poll spin instead of an efficient blocking wakeup.

Add a disableImmediateMode field (default false, preserving existing
behavior) so callers can opt out of immediate mode and let libpcap use
TPACKET_V3 with blocking, batched reads bounded by
packetBufferTimeoutMs. A loopback benchmark comparing both modes under
synthetic UDP flood showed ~14x lower capture-thread CPU usage and
~1.7x higher throughput with immediate mode disabled.

Co-authored-by: Cursor <cursoragent@cursor.com>
Trim redundant restating of behavior in favor of the why: TPACKET_V2
vs TPACKET_V3 and busy-poll vs blocking wait tradeoffs.

Co-authored-by: Cursor <cursoragent@cursor.com>
Lead with what the flag does, add a manpage reference, and match the
style used by other DeviceConfiguration fields in this file.

Co-authored-by: Cursor <cursoragent@cursor.com>
With immediate mode disabled, the packet buffer timeout controls
delivery latency, but the platform default passed to pcap_set_timeout
was -1 on Linux/Windows, which libpcap documents as unpredictable and
which can delay delivery until a ring block fills. Fall back to 100 ms
when packetBufferTimeoutMs is not set, drop the manpage URL from the
doc comment, and fix a continuation-line alignment nit.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The disableImmediateMode timeout fallback was unconditionally
substituting 100ms whenever packetBufferTimeoutMs was unset, clobbering
the small positive LIBPCAP_OPEN_LIVE_TIMEOUT already used on
FreeBSD/macOS to work around a pcap_breakloop() bug. Only fall back to
100ms when the platform default is itself non-positive (Linux/Windows),
leaving FreeBSD/macOS behavior unchanged regardless of
disableImmediateMode.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@codecov

codecov Bot commented Aug 5, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 83.33333% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.01%. Comparing base (200853b) to head (0be735f).

Files with missing lines Patch % Lines
Pcap++/src/PcapLiveDevice.cpp 77.77% 0 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##              dev    #2210      +/-   ##
==========================================
+ Coverage   81.30%   83.01%   +1.71%     
==========================================
  Files         319      328       +9     
  Lines       52180    59679    +7499     
  Branches    12124    12455     +331     
==========================================
+ Hits        42423    49544    +7121     
- Misses       7519     9143    +1624     
+ Partials     2238      992    -1246     
Flag Coverage Δ
23.11.6 7.28% <0.00%> (?)
24.11.5 7.26% <0.00%> (?)
alpine320 76.86% <81.81%> (+<0.01%) ⬆️
fedora42 76.45% <81.81%> (+0.01%) ⬆️
macos-15 82.26% <83.33%> (+<0.01%) ⬆️
macos-26 82.27% <83.33%> (+<0.01%) ⬆️
macos-26-intel ?
mingw32 71.48% <100.00%> (+<0.01%) ⬆️
mingw64 71.46% <100.00%> (+0.09%) ⬆️
rhel94 76.23% <81.81%> (+<0.01%) ⬆️
ubuntu2204 76.27% <81.81%> (+<0.01%) ⬆️
ubuntu2404 76.58% <81.81%> (+0.02%) ⬆️
ubuntu2604 76.51% <81.81%> (-0.02%) ⬇️
ubuntu2604-arm64 76.34% <81.81%> (+<0.01%) ⬆️
ubuntu2604-icpx 59.10% <70.00%> (+0.04%) ⬆️
unittest 83.01% <83.33%> (+1.71%) ⬆️
windows-2022 85.80% <100.00%> (?)
windows-2025 85.53% <100.00%> (?)
winpcap 85.83% <100.00%> (?)
xdp ?

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread Pcap++/header/PcapLiveDevice.h Outdated
Comment on lines +321 to +328
/// Disable libpcap's "immediate mode", which PcapPlusPlus enables by default (where supported) for
/// minimal packet delivery latency. On Linux, immediate mode also forces a less efficient capture
/// path (TPACKET_V2 with non-blocking polling, instead of TPACKET_V3 with blocking, batched reads),
/// which can hurt throughput and CPU usage at high packet rates. Setting this to true trades some
/// added latency (up to packetBufferTimeoutMs, or 100 ms on Linux/Windows if not set) for those
/// throughput and CPU benefits.
/// Default value is false.
bool disableImmediateMode;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

IMO, positive flags are easier to reason about than negative flags since the reader does not have to negate the condition. useImmediateMode defaulted to true might be easier to reason about when looking through the docs.

Also, I am wondering, do you think it would be better to have the flag be an enum instead of a bool?

Something like:

enum class BufferingMode
{
  Default, // let the device decide (current behavior)
  Immediate, // use immediate mode
  Buffered // use buffered mode
}

Default mode can also possibly have a graceful fallback to buffered, if immediate mode fails to enable for some reason.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

yeah good idea, Ill change

@MerinoSheep
MerinoSheep marked this pull request as ready for review August 19, 2026 09:31
@MerinoSheep
MerinoSheep requested a review from seladb as a code owner August 19, 2026 09:31
Use an enum class (Default/Immediate/Buffered) instead of a boolean flag,
per review discussion.
Reformat throw to a single line per clang-format, and suppress a
cppcheck knownConditionTrueFalse false positive on platforms where
LIBPCAP_OPEN_LIVE_TIMEOUT is a positive constant.
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