From c88a010aae39775a86ec9d38f29c614b2d1617dd Mon Sep 17 00:00:00 2001 From: Christian Deacon Date: Mon, 10 Mar 2025 17:08:03 -0400 Subject: [PATCH] Rework IPv6 header matching with dynamic filters and add packet length to logging event. --- src/common/types.h | 5 ++++- src/loader/utils/logging.c | 2 +- src/xdp/prog.c | 20 ++++++++++---------- src/xdp/utils/logging.c | 5 ++++- src/xdp/utils/logging.h | 2 +- 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/common/types.h b/src/common/types.h index e7615e1..67cfd9a 100644 --- a/src/common/types.h +++ b/src/common/types.h @@ -142,6 +142,8 @@ struct filter_log_event u64 ts; int filter_id; + int length; + u32 src_ip; u32 src_ip6[4]; @@ -158,7 +160,8 @@ struct filter_log_event u64 bps; } typedef filter_log_event_t; -struct lpm_trie_key { +struct lpm_trie_key +{ u32 prefix_len; u32 data; } typedef LpmTrieKey; \ No newline at end of file diff --git a/src/loader/utils/logging.c b/src/loader/utils/logging.c index 6958e7e..9bdf387 100644 --- a/src/loader/utils/logging.c +++ b/src/loader/utils/logging.c @@ -163,7 +163,7 @@ int hdl_filters_rb_event(void* ctx, void* data, size_t sz) const char* protocol_str = get_protocol_str_by_id(e->protocol); - log_msg(cfg, 0, 0, "[FILTER %d] %s %s packet '%s:%d' => '%s:%d' (PPS => %llu, BPS => %llu, Filter Block Time => %llu)...", e->filter_id + 1, action, protocol_str, src_ip_str, htons(e->src_port), dst_ip_str, htons(e->dst_port), e->pps, e->bps, filter->block_time); + log_msg(cfg, 0, 0, "[FILTER %d] %s %s packet '%s:%d' => '%s:%d' (PPS => %llu, BPS => %llu, Filter Block Time => %llu, length => %d)...", e->filter_id + 1, action, protocol_str, src_ip_str, htons(e->src_port), dst_ip_str, htons(e->dst_port), e->pps, e->bps, filter->block_time, e->length); return 0; } \ No newline at end of file diff --git a/src/xdp/prog.c b/src/xdp/prog.c index 7464544..3b84496 100644 --- a/src/xdp/prog.c +++ b/src/xdp/prog.c @@ -334,25 +334,25 @@ int xdp_prog_main(struct xdp_md *ctx) #endif // Max TTL length. - if (filter->ip.do_max_ttl && filter->ip.max_ttl > iph6->hop_limit) + if (filter->ip.do_max_ttl && filter->ip.max_ttl < iph6->hop_limit) { continue; } // Min TTL length. - if (filter->ip.do_min_ttl && filter->ip.min_ttl < iph6->hop_limit) + if (filter->ip.do_min_ttl && filter->ip.min_ttl > iph6->hop_limit) { continue; } // Max packet length. - if (filter->ip.do_max_len && filter->ip.max_len > (ntohs(iph6->payload_len) + sizeof(struct ethhdr))) + if (filter->ip.do_max_len && filter->ip.max_len < pkt_len) { continue; } // Min packet length. - if (filter->ip.do_min_len && filter->ip.min_len < (ntohs(iph6->payload_len) + sizeof(struct ethhdr))) + if (filter->ip.do_min_len && filter->ip.min_len > pkt_len) { continue; } @@ -400,33 +400,33 @@ int xdp_prog_main(struct xdp_md *ctx) continue; } - // Max TTL length. + // Max TTL. if (filter->ip.do_max_ttl && filter->ip.max_ttl < iph->ttl) { continue; } - // Min TTL length. + // Min TTL. if (filter->ip.do_min_ttl && filter->ip.min_ttl > iph->ttl) { continue; } // Max packet length. - if (filter->ip.do_max_len && filter->ip.max_len < (ntohs(iph->tot_len) + sizeof(struct ethhdr))) + if (filter->ip.do_max_len && filter->ip.max_len < pkt_len) { continue; } // Min packet length. - if (filter->ip.do_min_len && filter->ip.min_len > (ntohs(iph->tot_len) + sizeof(struct ethhdr))) + if (filter->ip.do_min_len && filter->ip.min_len > pkt_len) { continue; } } // PPS. - if (filter->do_pps && pps < filter->pps) + if (filter->do_pps && pps < filter->pps) { continue; } @@ -564,7 +564,7 @@ int xdp_prog_main(struct xdp_md *ctx) #ifdef ENABLE_FILTER_LOGGING if (filter->log > 0) { - log_filter_msg(iph, iph6, src_port, dst_port, protocol, now, pps, bps, i); + log_filter_msg(iph, iph6, src_port, dst_port, protocol, now, pps, bps, pkt_len, i); } #endif diff --git a/src/xdp/utils/logging.c b/src/xdp/utils/logging.c index e1d9473..43cef33 100644 --- a/src/xdp/utils/logging.c +++ b/src/xdp/utils/logging.c @@ -16,11 +16,12 @@ * @param now The timestamp. * @param pps The current PPS rate. * @param bps The current BPS rate. + * @param pkt_len The full packet length. * @param filter_id The filter ID that matched. * * @return always 0 */ -static __always_inline int log_filter_msg(struct iphdr* iph, struct ipv6hdr* iph6, u16 src_port, u16 dst_port, u8 protocol, u64 now, u64 pps, u64 bps, int filter_id) +static __always_inline int log_filter_msg(struct iphdr* iph, struct ipv6hdr* iph6, u16 src_port, u16 dst_port, u8 protocol, u64 now, u64 pps, u64 bps, int pkt_len, int filter_id) { filter_log_event_t* e = bpf_ringbuf_reserve(&map_filter_log, sizeof(*e), 0); @@ -47,6 +48,8 @@ static __always_inline int log_filter_msg(struct iphdr* iph, struct ipv6hdr* iph e->pps = pps; e->bps = bps; + e->length = pkt_len; + bpf_ringbuf_submit(e, 0); } diff --git a/src/xdp/utils/logging.h b/src/xdp/utils/logging.h index 7a5e25c..34301dd 100644 --- a/src/xdp/utils/logging.h +++ b/src/xdp/utils/logging.h @@ -6,7 +6,7 @@ #include #if defined(ENABLE_FILTERS) && defined(ENABLE_FILTER_LOGGING) -static __always_inline int log_filter_msg(struct iphdr* iph, struct ipv6hdr* iph6, u16 src_port, u16 dst_port, u8 protocol, u64 now, u64 pps, u64 bps, int filter_id); +static __always_inline int log_filter_msg(struct iphdr* iph, struct ipv6hdr* iph6, u16 src_port, u16 dst_port, u8 protocol, u64 now, u64 pps, u64 bps, int pkt_len, int filter_id); #endif // The source file is included directly below instead of compiled and linked as an object because when linking, there is no guarantee the compiler will inline the function (which is crucial for performance).