tc test 5
All checks were successful
Build and Deploy MITM Webserver / build (push) Successful in 9s

This commit is contained in:
2026-03-07 16:48:37 +01:00
parent ac849ba3fe
commit 29986d5073

View File

@@ -10,7 +10,6 @@ import hashlib
import ipaddress
import json
import signal
import shutil
import socket
import subprocess
import sys
@@ -44,7 +43,6 @@ EVENT_EGRESS = 2
EVENT_DROP = 3
INGRESS_PARENT = "ffff:fff2"
EGRESS_PARENT = "ffff:fff3"
MARK_FILTER_PREF = 10
INGRESS_FILTER_HANDLE = ":20"
EGRESS_FILTER_HANDLE = ":30"
@@ -114,6 +112,41 @@ struct event_t {
BPF_PERF_OUTPUT(ingress_events);
BPF_PERF_OUTPUT(meta_events);
struct counter_state {
struct bpf_spin_lock lock;
__u32 value;
};
struct {
__uint(type, BPF_MAP_TYPE_ARRAY);
__uint(max_entries, 1);
__type(key, __u32);
__type(value, struct counter_state);
} packet_counter SEC(".maps");
static __always_inline __u32 ensure_packet_mark(struct __sk_buff *skb) {
__u32 key = 0;
__u32 next = skb->mark;
struct counter_state *state;
if (next) {
return next;
}
state = bpf_map_lookup_elem(&packet_counter, &key);
if (!state) {
return 0;
}
bpf_spin_lock(&state->lock);
state->value += 1;
next = state->value;
bpf_spin_unlock(&state->lock);
skb->mark = next;
return next;
}
static __always_inline int parse_l3_l4_direct(struct event_t *event, void *data, void *data_end) {
struct ethhdr *eth = data;
__be16 eth_proto;
@@ -323,7 +356,7 @@ int handle_ingress(struct __sk_buff *skb) {
event.event_type = EVENT_INGRESS;
event.ifindex = skb->ifindex;
event.length = skb->len;
event.skb_mark = skb->mark;
event.skb_mark = ensure_packet_mark(skb);
if (!event.skb_mark) {
return TC_ACT_OK;
@@ -419,34 +452,6 @@ def _run_checked(cmd: list[str]) -> None:
subprocess.run(cmd, check=True, capture_output=True, text=True)
def _multiarch_include_flag() -> list[str]:
if shutil.which("gcc") is None:
return []
try:
triple = subprocess.run(["gcc", "-dumpmachine"], check=True, capture_output=True, text=True).stdout.strip()
except Exception:
return []
include_dir = Path("/usr/include") / triple
return [f"-I{include_dir}"] if include_dir.is_dir() else []
def _repo_root() -> Path:
return Path(__file__).resolve().parents[3]
def _ensure_mark_object(build_dir: str) -> Path:
build_path = Path(build_dir)
build_path.mkdir(parents=True, exist_ok=True)
src = _repo_root() / "tools" / "ebpf" / "mark_packet_id.c"
obj = build_path / "mark_packet_id.o"
if obj.exists() and obj.stat().st_mtime >= src.stat().st_mtime:
return obj
cmd = ["clang", "-O2", "-g", "-target", "bpf", *_multiarch_include_flag(), "-c", str(src), "-o", str(obj)]
_run_checked(cmd)
return obj
def _ifname_from_index(ifindex: int) -> str | None:
if ifindex <= 0:
return None
@@ -575,32 +580,9 @@ def _ensure_clean_clsact(iface: str) -> None:
_run_checked(["tc", "qdisc", "add", "dev", iface, "clsact"])
def _attach_mark_filter(iface: str, obj_path: Path) -> None:
_run_checked(
[
"tc",
"filter",
"replace",
"dev",
iface,
"ingress",
"pref",
str(MARK_FILTER_PREF),
"protocol",
"all",
"bpf",
"direct-action",
"obj",
str(obj_path),
"sec",
"classifier",
]
)
def _attach_tc_programs(bpf: BPF, ifaces: list[str], build_dir: str) -> tuple[str, str]:
global IPR
obj_path = _ensure_mark_object(build_dir)
del build_dir
ingress_fn = bpf.load_func("handle_ingress", BPF.SCHED_CLS)
egress_fn = bpf.load_func("handle_egress", BPF.SCHED_CLS)
@@ -612,7 +594,6 @@ def _attach_tc_programs(bpf: BPF, ifaces: list[str], build_dir: str) -> tuple[st
raise RuntimeError(f"Interface not found: {iface}")
ifindex = matches[0]
_ensure_clean_clsact(iface)
_attach_mark_filter(iface, obj_path)
ipr.tc(
"add-filter",
"bpf",