Skip to content

Feature gap: dataplane events (PolicyDeny, ScreenDrop, FilterLog) not emitted by userspace-dp #1379

@psaab

Description

@psaab

Gap

The eBPF dataplane emits per-event records into a ring buffer at policy-deny, screen-drop, and filter-log decision points. pkg/logging/ringbuf.go consumes the ring buffer and produces RT_FLOW_SESSION_DENY, screen-drop, and filter-log syslog messages in vSRX-compatible format. The userspace dataplane's event stream (userspace-dp/src/event_stream/) emits ONLY SessionOpen/Close/Update. Once eBPF is removed, syslog will lose per-flow deny / screen-drop / filter-log telemetry — operators rely on these for IDS visibility and audit.

eBPF implementation (source of truth)

  • bpf/headers/xpf_common.h:226-231 — six event types: EVENT_TYPE_SESSION_OPEN/CLOSE/POLICY_DENY/SCREEN_DROP/ALG_REQUEST/FILTER_LOG
  • bpf/xdp/xdp_screen.c / bpf/xdp/xdp_policy.c — call emit_event(meta, EVENT_TYPE_*, ...) to ringbuf at drop/deny points
  • pkg/logging/ringbuf.go:466-488 — type dispatch consuming these event types
  • pkg/logging/ringbuf.go:603RT_FLOW_SESSION_DENY ... emitted from EventTypePolicyDeny
  • pkg/daemon/daemon_run.go:352-388 — daemon wires dp.NewEventSource() ring buffer into EventReader

Userspace-dp gap

  • userspace-dp/src/event_stream/codec.rs:17-27 — defines MSG_SESSION_OPEN/CLOSE/UPDATE/ACK/PAUSE/RESUME/DRAIN_REQUEST/DRAIN_COMPLETE/FULL_RESYNC/KEEPALIVE; NO PolicyDeny / ScreenDrop / FilterLog frames
  • grep -rn 'EVENT_TYPE_POLICY_DENY\\|EVENT_TYPE_SCREEN_DROP\\|EVENT_TYPE_FILTER_LOG' userspace-dp/src/ — zero matches
  • Counter rollups are sent (pkg/dataplane/userspace/manager_ha.go:500-530) but those are aggregate, not per-event with src/dst/zone/policy_id needed for RT_FLOW_SESSION_DENY
  • The userspace Manager embeds the eBPF DataPlane so NewEventSource() still works today via the legacy BPF programs (which the userspace XDP shim tail-calls into for fallback). Once those programs are removed, the ring buffer has no producer

Recommended fix

Two-part change:

  1. Rust side (userspace-dp/src/event_stream/): extend EventFrame with new message types MSG_POLICY_DENY=11, MSG_SCREEN_DROP=12, MSG_FILTER_LOG=13; emit at the same decision points the legacy BPF programs did (policy denial in policy.rs, screen drop in screen.rs, filter log term in filter/engine.rs). Frame should carry src/dst/proto/zone-pair/policy-id/rule-id/timestamp.
  2. Go side (pkg/dataplane/userspace/eventstream.go + pkg/logging/): add a userspace EventSource implementation that consumes these new frame types and produces the same dataplane.Event records pkg/logging/ringbuf.go already handles. Alternatively rewrite ringbuf.go to consume the userspace JSON/binary protocol directly when dp.Mode() == ModeUserspace.

Blocker for #1373

This must land before Phase 4 (BPF source removal) of #1373 (retire eBPF dataplane). Loss of per-flow deny/screen-drop/filter-log syslog is a security visibility regression that breaks operator IDS/audit workflows.


Refined contract (added 2026-05-17 after triple-review of #1384)

See docs/pr/1373-retire-ebpf-dataplane/plan-1379-dataplane-events.md for the full implementation contract refined through 4 rounds of Claude+Codex+Gemini Pro 3 review. New since the original issue body:

  • Risks called out: event-loss accounting (drop counters per event-type when ring-buffer backpressure trips), syslog dedup (cluster failover must not duplicate events across peers, must not lose them), identity stability (PolicyDeny/ScreenDrop/FilterLog must carry the same RT_FLOW-shaped fields across both backends so syslog consumers don't regress).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions