From 28b7aa2266f598032e6fc6629dd5e116b05d989a Mon Sep 17 00:00:00 2001 From: Rodrigo Bertoldo de Sousa Martins Date: Mon, 14 Sep 2026 13:40:03 -0300 Subject: [PATCH] fixed4340 --- ebpf-sockmap/Makefile | 3 ++- ebpf-sockmap/bpf/sockmap.bpf.c | 24 +++++++++++++++++------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/ebpf-sockmap/Makefile b/ebpf-sockmap/Makefile index 8785e3e..0a56913 100644 --- a/ebpf-sockmap/Makefile +++ b/ebpf-sockmap/Makefile @@ -38,7 +38,8 @@ BPF_CFLAGS := -O2 -g \ -Wall \ -Wno-unused-value \ -Wno-pointer-sign \ - -Wno-compare-distinct-pointer-types + -Wno-compare-distinct-pointer-types \ + -Wno-missing-declarations # ─── Alvos principais ─── .PHONY: all vmlinux bpf clean docker-up docker-down load unload status benchmark help diff --git a/ebpf-sockmap/bpf/sockmap.bpf.c b/ebpf-sockmap/bpf/sockmap.bpf.c index a81cc1d..e29a874 100644 --- a/ebpf-sockmap/bpf/sockmap.bpf.c +++ b/ebpf-sockmap/bpf/sockmap.bpf.c @@ -83,13 +83,22 @@ static __always_inline void stats_inc(__u32 idx) // Verifica se um endereço IPv6 é, na verdade, um IPv4 mapeado // (::ffff:a.b.c.d, RFC 4291 §2.5.5.2: 80 bits zero + 16 bits 0xffff + // 32 bits do IPv4) e extrai o IPv4 equivalente. -static __always_inline bool ipv4_mapped(const __u32 ip6[4], __u32 *out_ip4) +// +// Recebe os 4 words POR VALOR (w0..w3), não um ponteiro/array — passar +// o endereço de um campo array do ctx (ex: &ops->local_ip6[0]) pra uma +// função separada é "aritmética de ponteiro modificado no ctx", que o +// verificador do BPF rejeita (bpf_sock_ops/sk_msg_md só permitem acesso +// direto a campos em offsets conhecidos, reescrito pelo compilador; +// tirar o endereço de um array de campo quebra esse reconhecimento). +// Cada chamador lê os 4 elementos diretamente (ops->local_ip6[0] etc) +// e passa os valores, não o array. +static __always_inline bool ipv4_mapped(__u32 w0, __u32 w1, __u32 w2, __u32 w3, __u32 *out_ip4) { - if (ip6[0] != 0 || ip6[1] != 0) + if (w0 != 0 || w1 != 0) return false; - if (bpf_ntohl(ip6[2]) != 0x0000ffff) + if (bpf_ntohl(w2) != 0x0000ffff) return false; - *out_ip4 = ip6[3]; + *out_ip4 = w3; return true; } @@ -160,8 +169,8 @@ extract_key_from_ops(struct bpf_sock_ops *ops, struct sock_key *key) local_ip4 = ops->local_ip4; remote_ip4 = ops->remote_ip4; } else if (ops->family == SOCKMAP_AF_INET6) { - if (!ipv4_mapped(ops->local_ip6, &local_ip4) || - !ipv4_mapped(ops->remote_ip6, &remote_ip4)) + if (!ipv4_mapped(ops->local_ip6[0], ops->local_ip6[1], ops->local_ip6[2], ops->local_ip6[3], &local_ip4) || + !ipv4_mapped(ops->remote_ip6[0], ops->remote_ip6[1], ops->remote_ip6[2], ops->remote_ip6[3], &remote_ip4)) return false; } else { return false; @@ -296,7 +305,8 @@ int bpf_msg_redirect(struct sk_msg_md *msg) sip4 = msg->remote_ip4; dip4 = msg->local_ip4; } else if (msg->family == SOCKMAP_AF_INET6) { - if (!ipv4_mapped(msg->remote_ip6, &sip4) || !ipv4_mapped(msg->local_ip6, &dip4)) { + if (!ipv4_mapped(msg->remote_ip6[0], msg->remote_ip6[1], msg->remote_ip6[2], msg->remote_ip6[3], &sip4) || + !ipv4_mapped(msg->local_ip6[0], msg->local_ip6[1], msg->local_ip6[2], msg->local_ip6[3], &dip4)) { stats_inc(2); // IPv6 de verdade — nunca deveria estar no mapa, mas por segurança cai no fallback return SK_PASS; }