fix(marker): per-link attribution via link field in MARK signals

A uBridge MARK signal carries only node= and filter= (no bridge/link field), so when one node is the capture side for several links that share a marker name (always the case for global-{name} definitions on a multi-interface node) the signals were indistinguishable and the (node, filter) registry collapsed them to a single link.

The mark filter is now stamped with its link id (mark <bpf> ... link <link_id>); uBridge echoes it verbatim (link=<link_id>) and the listener uses the signal's link= as the authoritative link_id of the marker.match event, falling back to the registry only for legacy signals without it. base_node and iou apply paths pass link_id; covered by two new listener tests.
This commit is contained in:
YueGuobin committed 2026-07-16 00:39:52 +08:00
1 parent 27356da62d
commit 794bfef450
4 files changed
+42 -3

No files matched your search

+7 -2
View File
@@ -1073,7 +1073,7 @@ class BaseNode:
)
i += 1
async def _ubridge_add_marker_filter(self, bridge_name, name, bpf, pcap_path, tag=None):
async def _ubridge_add_marker_filter(self, bridge_name, name, bpf, pcap_path, tag=None, link_id=None):
"""
Attach a `mark` packet filter to a uBridge bridge for traffic insight.
@@ -1104,6 +1104,11 @@ class BaseNode:
)
if tag is not None:
cmd += f" tag {tag}"
# Per-link attribution (contract §3.2): when one ubridge bridge serves
# several GNS3 links (e.g. IOU's per-node bridge), bridge+filter collide,
# so the link id is the only way to tell signals — and pcap files — apart.
if link_id:
cmd += f" link {link_id}"
cmd += ' pcap "{path}"'.format(path=pcap_path)
# Let BPF compile errors propagate — the marker is the user's intent, so a
# bad expression must surface instead of being silently dropped.
@@ -1133,7 +1138,7 @@ class BaseNode:
markers_dir, f"{self._id}_{link_id}_{name}.pcap"
)
try:
await self._ubridge_add_marker_filter(bridge_name, name, bpf, pcap_path, tag)
await self._ubridge_add_marker_filter(bridge_name, name, bpf, pcap_path, tag, link_id)
except UbridgeError as e:
# Swallow BPF compile errors (warn + skip) so a single bad
# expression can't break link creation / node restart — mirrors