Skip to content

fix(cpworker): keep the L2 header stack under zmq slice and count runt drops - #302

Merged
timmy21 merged 1 commit into
0.9.xfrom
fix/271-zmq-runt-accounting
Oct 8, 2026
Merged

timmy21 merged 1 commit into
0.9.xfrom
fix/271-zmq-runt-accounting

Conversation

@timmy21

@timmy21 timmy21 commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Problem

  • A zmq output with slice < 18 dropped every packet. slice was applied first, then a fixed 18-byte minimum rejected the result. docs/ZMQ-WIRE-FORMAT.md said slice keeps at least Ethernet + one VLAN header.
  • Dropped runt frames only incremented the internal nb_too_small_packets counter. No output statistic changed, so fwd + direction_drop + error_drop + ratelimit_drop did not add up to the packets the output handled.
  • The 18-byte minimum was a leftover guard from before [cpworker] output_zmq.c: VLAN-aware slicing causes size_t underflow and out-of-bounds memcpy #231. It rejected valid untagged frames of 14–17 bytes, and still let slice cut into a QinQ tag stack (slice: 18 kept the outer tag and rewrote its EtherType to 0x8847).

Change

slice truncates the payload only; the Ethernet header and the whole VLAN tag stack are always kept.

  • l2_header_len() measures Ethernet + complete tag stack on the original caplen, before slice is applied.
  • Effective caplen with slice is max(slice, l2_len).
  • A frame whose Ethernet header or tag stack was not fully captured produces no record and is counted in error_drop_packets / error_drop_bytes. The nb_too_small_packets warning stays and now names the reason.
  • The second VLAN walk in zmq_send_packet is removed; the record reuses l2_len.
  • docs/ZMQ-WIRE-FORMAT.md §1 and §4.1 describe the new rule.
Case Before After
slice: 10, one VLAN tag dropped, not counted 18-byte record
slice: 18, QinQ inner tag cut, outer EtherType rewritten 22-byte record, both tags
slice: 26, 4 tags (#231 frame) 26 bytes, 3 tags 30 bytes, 4 tags
untagged, 14–17 bytes dropped, not counted sent
< 14 bytes, or cut tag dropped, not counted dropped, error_drop

The two #231 tests are rewritten for the new rule. The 60-byte frame filled with 0x8100 tags has a tag stack that never ends within caplen, so it is now an error_drop instead of a record with 11 tags.

Tests

cpworker/tests/unit/output_zmq.c: slice keeps one tag / both QinQ tags / the 4-tag stack / the untagged header; 14-byte untagged frame sent; < 14 bytes, cut tag and unterminated tag stack counted as error_drop; a runt plus a normal frame gives fwd = 1, error_drop = 1.

  • Unit tests: 9/9 suites pass.
  • Integration tests: run_test.sh all passes.

Fixes #271

…t drops

A zmq output dropped every packet when slice was below 18 bytes, because
slice was applied before the fixed 18-byte minimum. The dropped packets
were not counted in any output statistic.

slice now truncates the payload only. The record always keeps the
Ethernet header and the whole VLAN tag stack. A frame whose Ethernet
header or tag stack was not fully captured produces no record and is
counted as error_drop. The fixed 18-byte minimum is gone: untagged
frames need 14 bytes, and QinQ frames keep both tags.
@timmy21
timmy21 merged commit e5b3d98 into 0.9.x Oct 8, 2026
1 check passed
@timmy21
timmy21 deleted the fix/271-zmq-runt-accounting branch October 8, 2026 02:42
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.

cpworker: zmq output drops runt frames without counting them in any stats counter

1 participant