fixed4337

This commit is contained in:
Rodrigo Bertoldo de Sousa Martins committed 2026-09-14 09:24:18 -03:00
1 parent 0a37f06ce6
commit e97a83c989
2 files changed
+34 -5

No files matched your search

+25 -4
View File
@@ -97,13 +97,30 @@ static __always_inline bool is_local_ip(__u32 ip_be)
// Extrai a chave de conexão a partir do contexto sock_ops // Extrai a chave de conexão a partir do contexto sock_ops
// (usado quando uma conexão TCP é estabelecida) // (usado quando uma conexão TCP é estabelecida)
// ───────────────────────────────────────────────────────── // ─────────────────────────────────────────────────────────
// BUG CORRIGIDO: o código antigo misturava dois domínios de codificação
// de porta sem converter os dois pro mesmo formato.
// - ops->local_port vem em HOST byte order (puro, ex: 6379)
// - ops->remote_port vem com o valor em network byte order alojado nos
// 16 bits SUPERIORES de um campo de 32 bits — não é um u32 comum em
// network order, então bpf_ntohl() sozinho faz um byte-swap completo
// de 32 bits e produz um número sem relação com a porta real.
// A comparação `sport == local_port do outro lado` só funciona se AMBOS
// os valores estiverem no MESMO domínio. Em vez de tentar decifrar o
// valor "verdadeiro" da porta (o que exigiria confiar numa convenção que
// não dá pra validar sem testar em kernel real), a correção normaliza os
// dois pro domínio de remote_port: extrai remote_port com ">> 16" (sem
// ntohl) e converte local_port PRA esse mesmo domínio com
// "bpf_htonl(local_port) >> 16". Assim os dois lados de uma conexão
// calculam exatamente o mesmo valor pro mesmo par de portas, não importa
// qual seja a codificação exata do kernel — o que importa é que os dois
// membros do par usem a MESMA transformação simétrica.
static __always_inline void static __always_inline void
extract_key_from_ops(struct bpf_sock_ops *ops, struct sock_key *key) extract_key_from_ops(struct bpf_sock_ops *ops, struct sock_key *key)
{ {
key->sip4 = ops->local_ip4; key->sip4 = ops->local_ip4;
key->dip4 = ops->remote_ip4; key->dip4 = ops->remote_ip4;
key->sport = ops->local_port; // já em host byte order key->sport = bpf_htonl(ops->local_port) >> 16;
key->dport = bpf_ntohl(ops->remote_port); // converter de network para host key->dport = ops->remote_port >> 16;
key->family = ops->family; key->family = ops->family;
} }
@@ -201,11 +218,15 @@ int bpf_msg_redirect(struct sk_msg_md *msg)
// Construímos a chave do socket PAR (invertendo src/dst). // Construímos a chave do socket PAR (invertendo src/dst).
// Se A→B enviou dados, queremos encontrar no mapa a entrada // Se A→B enviou dados, queremos encontrar no mapa a entrada
// que B registrou: {sip=B, dip=A, sport=portaB, dport=portaA} // que B registrou: {sip=B, dip=A, sport=portaB, dport=portaA}
//
// Mesma normalização de porta usada em extract_key_from_ops (mesmo
// domínio dos dois lados): remote_port só com ">> 16", local_port
// convertido pra esse domínio via "bpf_htonl(...) >> 16".
struct sock_key key = {}; struct sock_key key = {};
key.sip4 = msg->remote_ip4; // IP remoto = IP do par key.sip4 = msg->remote_ip4; // IP remoto = IP do par
key.dip4 = msg->local_ip4; // IP local = nosso IP key.dip4 = msg->local_ip4; // IP local = nosso IP
key.sport = bpf_ntohl(msg->remote_port); // remote_port está em network order key.sport = msg->remote_port >> 16;
key.dport = msg->local_port; // local_port está em host order key.dport = bpf_htonl(msg->local_port) >> 16;
key.family = msg->family; key.family = msg->family;
// Tenta redirecionar diretamente para o socket par. // Tenta redirecionar diretamente para o socket par.
+9 -1
View File
@@ -52,4 +52,12 @@ ip link set dev wg0 xdp obj /home/rodrigo/server-mv/xdp/xdp_wg_mtu_optimizer.o s
# então esse link precisa ser reaplicado se a rede "dockernet" for recriada. # então esse link precisa ser reaplicado se a rede "dockernet" for recriada.
ip link set dev br-02f7820020b4 xdp obj /home/rodrigo/server-mv/xdp/bridge_xdp.o sec xdp ip link set dev br-02f7820020b4 xdp obj /home/rodrigo/server-mv/xdp/bridge_xdp.o sec xdp
cd /home/docker/ebpf-sockmap/ && make load # eBPF sockmap: DESATIVADO DE PROPÓSITO. Causou timeout/connection reset
# em conexões container-a-container (nginx->redis/mariadb/anatomia-web),
# incluindo depois de corrigir o bug de NAT (masquerade sem -o enp0s6,
# já corrigido em nftables.conf) — ou seja, o bug é na lógica de
# match/redirect do sk_msg em bpf/sockmap.bpf.c, não só no NAT. Não
# reativar em produção sem antes rastrear com bpf_printk num ambiente
# de teste. Ganho é só performance (bypass de socket local entre
# containers no mesmo host); o site funciona normalmente sem isso.
# cd /home/docker/ebpf-sockmap/ && make load