diff --git a/backend/src/utilities/capture_pipeline.py b/backend/src/utilities/capture_pipeline.py index 86087f4..df96bde 100644 --- a/backend/src/utilities/capture_pipeline.py +++ b/backend/src/utilities/capture_pipeline.py @@ -13,6 +13,21 @@ from src.config import settings logger = logging.getLogger("capture_pipeline") +def _run_checked(cmd: list[str]) -> subprocess.CompletedProcess[str]: + """Run a command and surface stdout/stderr in raised errors.""" + try: + return subprocess.run(cmd, check=True, capture_output=True, text=True) + except subprocess.CalledProcessError as exc: + stdout = (exc.stdout or "").strip() + stderr = (exc.stderr or "").strip() + if stdout: + logger.error("Command stdout for %s:\n%s", cmd[0], stdout) + if stderr: + logger.error("Command stderr for %s:\n%s", cmd[0], stderr) + detail = stderr or stdout or str(exc) + raise RuntimeError(detail) from exc + + class CapturePipelineManager: """Reference-count mirrored capture pipelines per bridge.""" @@ -107,7 +122,7 @@ class CapturePipelineManager: mirror_if, capture_if, ) - subprocess.run(cmd, check=True, capture_output=True, text=True) + _run_checked(cmd) self._active[bridge] = { "mirror_if": mirror_if, "capture_if": capture_if, @@ -134,7 +149,7 @@ class CapturePipelineManager: mirror_if, capture_if, ) - subprocess.run(cmd, check=True, capture_output=True, text=True) + _run_checked(cmd) def _repo_root(self) -> Path: return Path(__file__).resolve().parents[3] diff --git a/tools/setup_bridge_capture.sh b/tools/setup_bridge_capture.sh index 30ea623..303ac87 100755 --- a/tools/setup_bridge_capture.sh +++ b/tools/setup_bridge_capture.sh @@ -36,8 +36,13 @@ if [[ -z "$BRIDGE" ]]; then exit 1 fi -if ! command -v tc >/dev/null 2>&1 || ! command -v clang >/dev/null 2>&1; then - echo "Missing required tools: tc and clang must be installed." >&2 +if ! command -v tc >/dev/null 2>&1 || ! command -v clang >/dev/null 2>&1 || ! command -v ip >/dev/null 2>&1 || ! command -v bridge >/dev/null 2>&1; then + echo "Missing required tools: tc, clang, ip, and bridge must be installed." >&2 + exit 1 +fi + +if ! ip link show "$BRIDGE" >/dev/null 2>&1; then + echo "Bridge interface not found: $BRIDGE" >&2 exit 1 fi @@ -46,9 +51,16 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SRC_DIR="$SCRIPT_DIR/ebpf" MARK_OBJ="$BUILD_DIR/mark_packet_id.o" CAPTURE_OBJ="$BUILD_DIR/prepend_capture_header.o" +MULTIARCH_INCLUDE="" +if command -v gcc >/dev/null 2>&1; then + GCC_TRIPLE="$(gcc -dumpmachine 2>/dev/null || true)" + if [[ -n "$GCC_TRIPLE" && -d "/usr/include/$GCC_TRIPLE" ]]; then + MULTIARCH_INCLUDE="-I/usr/include/$GCC_TRIPLE" + fi +fi -clang -O2 -g -target bpf -c "$SRC_DIR/mark_packet_id.c" -o "$MARK_OBJ" -clang -O2 -g -target bpf -c "$SRC_DIR/prepend_capture_header.c" -o "$CAPTURE_OBJ" +clang -O2 -g -target bpf ${MULTIARCH_INCLUDE:+$MULTIARCH_INCLUDE} -c "$SRC_DIR/mark_packet_id.c" -o "$MARK_OBJ" +clang -O2 -g -target bpf ${MULTIARCH_INCLUDE:+$MULTIARCH_INCLUDE} -c "$SRC_DIR/prepend_capture_header.c" -o "$CAPTURE_OBJ" if ! ip link show "$MIRROR_IF" >/dev/null 2>&1; then ip link add "$MIRROR_IF" type veth peer name "$CAPTURE_IF"