Opt-in per-packet capture-leg (source_idx) on Packet events for full leg fidelity #121

Closed
opened 2026-06-28 20:56:51 +00:00 by p13marc · 0 comments
p13marc commented 2026-06-28 20:56:51 +00:00 (Migrated from github.com)

Part of the tap-merge three-axis epic. Phase 3 — optional, audit-grade
fidelity. Independent of the core #71 fix.

Why

Phase 2 folds the capture leg to a per-direction binding on FlowStats
— correct and cheap for a correctly-wired tap (one NIC per canonical
orientation). But some use cases need per-packet leg attribution:

  • Auditing a tap/SPAN for packets arriving on the "wrong" leg
    (asymmetric routing, mis-wiring, LACP hashing surprises).
  • Forensic per-packet provenance ("this exact packet came from NIC 1").

For these, a per-direction summary isn't enough — you need the leg on
each Packet event.

Proposed change (opt-in)

Add an opt-in per-packet source_idx (or capture_leg: Option<u32>)
to Event::Packet / FlowEvent::Packet, populated from
view.rx_metadata.source_idx, gated behind a builder/config knob
(mirroring how Event::Packet.tcp is opt-in via
DriverBuilder::emit_packet_details today — src/driver/typed.rs).
Default off so the hot path and the common merged-mode consumer pay
nothing.

  • Reuse the same #[non_exhaustive] Packet variants introduced by the
    Phase-1 fix, so this is an additive field add at that point.
  • Document that this is the audit/forensic tier; the per-direction
    binding (Phase 2) is the mainstream answer.

Acceptance criteria

  • With the knob off (default), no per-packet leg field is populated and
    there is zero added hot-path cost.
  • With the knob on, every Packet event carries the originating
    source_idx.
  • A test feeding two NICs into one merged flow can reconstruct the exact
    per-packet leg sequence.

Dependencies

  • Phase-1 fix (the #[non_exhaustive] Packet variants) so the field add
    is additive.
  • Motivated independently of #71's core; schedule on demand.

References

  • Per-packet leg precedent: pcapng EPB Interface ID
    (https://pcapng.com/), gopacket CaptureInfo.InterfaceIndex,
    AF_PACKET sll_ifindex, PF_RING if_index.
  • plans/issue-71-tap-merge-orientation.md (§4 option 2, §5 Phase 3)
Part of the tap-merge three-axis epic. Phase 3 — optional, audit-grade fidelity. Independent of the core #71 fix. ## Why Phase 2 folds the capture leg to a per-direction binding on `FlowStats` — correct and cheap for a correctly-wired tap (one NIC per canonical orientation). But some use cases need **per-packet** leg attribution: - Auditing a tap/SPAN for **packets arriving on the "wrong" leg** (asymmetric routing, mis-wiring, LACP hashing surprises). - Forensic per-packet provenance ("this exact packet came from NIC 1"). For these, a per-direction summary isn't enough — you need the leg on each `Packet` event. ## Proposed change (opt-in) Add an **opt-in** per-packet `source_idx` (or `capture_leg: Option<u32>`) to `Event::Packet` / `FlowEvent::Packet`, populated from `view.rx_metadata.source_idx`, gated behind a builder/config knob (mirroring how `Event::Packet.tcp` is opt-in via `DriverBuilder::emit_packet_details` today — `src/driver/typed.rs`). Default off so the hot path and the common merged-mode consumer pay nothing. - Reuse the same `#[non_exhaustive]` Packet variants introduced by the Phase-1 fix, so this is an additive field add at that point. - Document that this is the audit/forensic tier; the per-direction binding (Phase 2) is the mainstream answer. ## Acceptance criteria - With the knob off (default), no per-packet leg field is populated and there is zero added hot-path cost. - With the knob on, every `Packet` event carries the originating `source_idx`. - A test feeding two NICs into one merged flow can reconstruct the exact per-packet leg sequence. ## Dependencies - Phase-1 fix (the `#[non_exhaustive]` Packet variants) so the field add is additive. - Motivated independently of #71's core; schedule on demand. ## References - Per-packet leg precedent: pcapng EPB Interface ID (https://pcapng.com/), gopacket `CaptureInfo.InterfaceIndex`, AF_PACKET `sll_ifindex`, PF_RING `if_index`. - `plans/issue-71-tap-merge-orientation.md` (§4 option 2, §5 Phase 3)
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
marcpardo/flowscope#121
No description provided.