marker: point directional defs at BPF, refresh implementation doc

The 409 on a tx/rx definition now recommends encoding direction in the BPF
(e.g. icmp[icmptype]==8) as the primary fix, with per-link markers as the
single-link fallback. Doc updated: per-def rejects tx/rx (why + BPF), the
pause section no longer claims bpf changes reset+reapply (they rebuild one
filter), and a new Capture files section covers pcap cleanup + reset-preserves-mark.
This commit is contained in:
YueGuobin 2026-08-04 22:59:12 +08:00
parent 95824b1861
commit 60e2bbbbbb
No known key found for this signature in database
2 changed files with 32 additions and 9 deletions

View File

@ -147,6 +147,13 @@ observer would silently flip the meaning of stored `direction`, so recreate the
instead). It is not accepted on project-level definitions — a definition is link-agnostic and
has no endpoints to choose from, so inherited markers always auto-pick per link.
For the same reason, a definition **rejects `direction: tx|rx`** (HTTP 409): each inherited
copy auto-picks its capture node, so a fixed tx/rx would denote different session directions
on different links. A definition is `both` only; encode the direction you want in the BPF
instead — e.g. `icmp and icmp[icmptype]==8` for echo requests, a packet-intrinsic property
that is consistent on every link regardless of capture node. tx/rx remains available on
per-link markers, where the capture node is fixed.
## Pause & resume
Two levels of silencing, both instant (no NIO rebuild, no pcap flush):
@ -156,8 +163,10 @@ Two levels of silencing, both instant (no NIO rebuild, no pcap flush):
`enable_packet_filter … off`): no signal, no pcap, but traffic still relays —
a paused `mark` is a no-op tap, not a drop. `{"enabled": true}` flips it back.
A change to `enabled` alone is a single command (the pcap identity and emitted
counter are preserved); changing `bpf` or other fields still goes through a
reset+reapply.
counter are preserved). Changing `bpf`, `tag`, or `direction` rebuilds just that
one filter (`delete_packet_filter` + add) — only that marker's own pcap reopens
(a new capture session for the new BPF); changing `color`/`highlight_duration`
is UI-only, nothing is pushed to uBridge.
- **Per-definition (inherited)**`POST /v3/projects/{pid}/marker-definitions/{name}/pause`
and `/resume` toggle **every** inherited `global-{name}` copy across all links
at once (same `enable_packet_filter on|off`, fanned out per copy). Use to
@ -172,6 +181,15 @@ Two levels of silencing, both instant (no NIO rebuild, no pcap flush):
| per-def `pause` (all `global-{name}` copies) | stop | stop | n/a |
| per-def `resume` | resume | resume | n/a |
## Capture files
Each marker appends matches to `<project>/project-files/markers/<node_id>_<link_id>_<filter>.pcap`.
Removing a marker — per-link `DELETE .../markers/{name}` or deleting a definition (which
removes every inherited copy) — deletes that marker's pcap too, even with the capture node
stopped (the filter is removed with `delete_packet_filter`, the file is unlinked). uBridge's
`reset_packet_filters` (run on NIO/filter changes) preserves mark filters, so unrelated
changes no longer close/reopen any marker's pcap.
## API Endpoints
All endpoints require a JWT bearer token (`POST /v3/access/users/authenticate`). The

View File

@ -967,17 +967,22 @@ class Project:
def _validate_marker_definition_direction(self, name, direction):
"""
Reject tx/rx on a marker definition: a definition auto-selects its
capture node per link (``_choose_marker_side``), while tx/rx is
interpreted from that node's perspective, so a fixed direction has no
stable meaning project-wide. Only 'both' (the default, = ``None``) is
allowed use a per-link marker if a directional filter is needed.
Reject tx/rx on a marker definition: a definition fans out to every link
and auto-selects its capture node on each (``_choose_marker_side``),
while tx/rx is relative to that node, so a fixed direction has no
consistent meaning across links. Only 'both' (the default, = ``None``)
is allowed encode the direction in the BPF instead (e.g.
``icmp[icmptype]==8`` for echo requests), or use a per-link marker whose
capture node is pinned.
"""
if direction in ("tx", "rx"):
raise ControllerError(
f"Marker definition '{name}': direction '{direction}' is not allowed. "
"A definition auto-selects its capture node per link and tx/rx is "
"relative to that node — use 'both' (the default), or a per-link marker."
"A definition fans out to every link and auto-selects its capture node on each, "
"but tx/rx is relative to that node, so a fixed direction has no consistent "
"meaning across links. Keep 'both' (the default) and encode the direction in "
"the BPF instead, e.g. 'icmp and icmp[icmptype]==8' for echo requests only. "
"For a capture-node-relative direction on a single link, use a per-link marker."
)
async def create_marker_definition(self, name, bpf, tag=None, direction=None, color=None, highlight_duration=None):