From aacb5dd1a44179f2ab0c92a1bf35a0a6f083ff47 Mon Sep 17 00:00:00 2001 From: Tizian Maxime Weigt Date: Tue, 28 Oct 2025 09:18:45 +0000 Subject: [PATCH] main.c aktualisiert --- main.c | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/main.c b/main.c index f81801f..5bac218 100644 --- a/main.c +++ b/main.c @@ -59,9 +59,9 @@ struct flow_stats { __u64 bytes; }; -/* Hash map to track stats per flow */ +/* PERCPU hash map to track stats per flow - NO LOCKING NEEDED */ struct { - __uint(type, BPF_MAP_TYPE_HASH); + __uint(type, BPF_MAP_TYPE_PERCPU_HASH); __uint(key_size, sizeof(struct flow_key)); __uint(value_size, sizeof(struct flow_stats)); __uint(max_entries, 65536); @@ -76,21 +76,22 @@ static __always_inline int ip_decrease_ttl(struct iphdr *iph) return --iph->ttl; } -/* Record stats in the xdp_flow_stats map */ +/* Record stats in the xdp_flow_stats map - OPTIMIZED for PERCPU */ static __always_inline void record_stats(struct xdp_md *ctx, struct flow_key *key, __u64 bytes) { struct flow_stats *stats; stats = bpf_map_lookup_elem(&xdp_flow_stats, key); if (stats) { - __sync_fetch_and_add(&stats->packets, 1); - __sync_fetch_and_add(&stats->bytes, bytes); + /* Direct update - no atomics needed with PERCPU maps */ + stats->packets++; + stats->bytes += bytes; } else { struct flow_stats new_stats = { .packets = 1, .bytes = bytes, }; - bpf_map_update_elem(&xdp_flow_stats, key, &new_stats, BPF_ANY); + bpf_map_update_elem(&xdp_flow_stats, key, &new_stats, BPF_NOEXIST); } } @@ -157,6 +158,9 @@ static __always_inline int xdp_l3fwd_flags(struct xdp_md *ctx, __u32 flags) if ((void *)(iph + 1) > data_end) return XDP_DROP; + if (iph->ttl <= 1) + return XDP_PASS; + key.proto = iph->protocol; key.ipv4_src = iph->saddr; key.ipv4_dst = iph->daddr; @@ -174,12 +178,6 @@ static __always_inline int xdp_l3fwd_flags(struct xdp_md *ctx, __u32 flags) } } - /* Record stats before forwarding */ - record_stats(ctx, &key, bytes); - - if (iph->ttl <= 1) - return XDP_PASS; - fib_params.family = AF_INET; fib_params.tos = iph->tos; fib_params.l4_protocol = iph->protocol; @@ -192,6 +190,9 @@ static __always_inline int xdp_l3fwd_flags(struct xdp_md *ctx, __u32 flags) if ((void *)(ip6h + 1) > data_end) return XDP_DROP; + if (ip6h->hop_limit <= 1) + return XDP_PASS; + key.proto = ip6h->nexthdr; __builtin_memcpy(key.ipv6_src, &ip6h->saddr, 16); __builtin_memcpy(key.ipv6_dst, &ip6h->daddr, 16); @@ -209,12 +210,6 @@ static __always_inline int xdp_l3fwd_flags(struct xdp_md *ctx, __u32 flags) } } - /* Record stats before forwarding */ - record_stats(ctx, &key, bytes); - - if (ip6h->hop_limit <= 1) - return XDP_PASS; - fib_params.family = AF_INET6; fib_params.flowinfo = *(__be32 *)ip6h & IPV6_FLOWINFO_MASK; fib_params.l4_protocol = ip6h->nexthdr; @@ -227,10 +222,14 @@ static __always_inline int xdp_l3fwd_flags(struct xdp_md *ctx, __u32 flags) fib_params.ifindex = ctx->ingress_ifindex; rc = bpf_fib_lookup(ctx, &fib_params, sizeof(fib_params), flags); + if (rc == BPF_FIB_LKUP_RET_SUCCESS) { if (!bpf_map_lookup_elem(&xdp_l3fwd_ports, &fib_params.ifindex)) return XDP_PASS; + /* Record stats AFTER fib lookup */ + record_stats(ctx, &key, bytes); + if (h_proto == bpf_htons(ETH_P_IP)) ip_decrease_ttl(iph); else if (h_proto == bpf_htons(ETH_P_IPV6))