nova tentativa de fix do ebpf-sockmap3

This commit is contained in:
Rodrigo Bertoldo de Sousa Martins committed 2026-09-14 15:13:47 -03:00
1 parent 424934def4
commit c17738a62f
1 file changed
+22 -3
+22 -3
View File
@@ -274,9 +274,31 @@ int bpf_sockops_handler(struct bpf_sock_ops *skops)
// Redireciona os dados diretamente para o socket par, // Redireciona os dados diretamente para o socket par,
// pulando toda a pilha de rede. // pulando toda a pilha de rede.
// ───────────────────────────────────────────────────────── // ─────────────────────────────────────────────────────────
// Acima deste tamanho, NÃO tentamos redirecionar — vai direto pro
// fallback (caminho normal de rede, já comprovado correto e íntegro por
// teste isolado de 500MB via nc). Motivo: evidência em produção (trace
// ao vivo) mostrou que rajadas grandes e sustentadas pelo caminho
// acelerado (BPF_F_INGRESS do sk_msg) corrompem a integridade do byte
// stream o suficiente pra quebrar framing HTTP/2 no cliente
// (ERR_HTTP2_PROTOCOL_ERROR), mesmo com bpf_msg_redirect_hash
// retornando sucesso (SK_PASS) em 100% dos casos — ou seja, o redirect
// "funciona" do ponto de vista da própria chamada, mas os dados que
// chegam do outro lado saem malformados. Não é bug de chave/family (já
// validamos ambos corretos); é uma limitação real do mecanismo de
// redirect desta kernel sob volume alto. Mensagens pequenas (onde a
// aceleração realmente importa — round-trips de banco/cache) continuam
// sendo redirecionadas normalmente; só streams grandes (modelos 3D,
// downloads) ficam de fora do caminho acelerado.
#define SOCKMAP_MAX_REDIRECT_SIZE 16384
SEC("sk_msg") SEC("sk_msg")
int bpf_msg_redirect(struct sk_msg_md *msg) int bpf_msg_redirect(struct sk_msg_md *msg)
{ {
if (msg->size > SOCKMAP_MAX_REDIRECT_SIZE) {
stats_inc(2);
return SK_PASS;
}
// 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}
@@ -303,9 +325,6 @@ int bpf_msg_redirect(struct sk_msg_md *msg)
// Tenta redirecionar diretamente para o socket par. // Tenta redirecionar diretamente para o socket par.
int ret = bpf_msg_redirect_hash(msg, &sock_hash, &key, BPF_F_INGRESS); int ret = bpf_msg_redirect_hash(msg, &sock_hash, &key, BPF_F_INGRESS);
// DEBUG TEMPORÁRIO — pra achar o bug de transferência grande.
if (msg->size > 8192)
bpf_printk("MSG grande dip=%x dport=%u size=%u ret=%d", key.dip4, key.dport, msg->size, ret);
if (ret == SK_PASS) { if (ret == SK_PASS) {
stats_inc(1); // Redirecionamento OK — caminho acelerado stats_inc(1); // Redirecionamento OK — caminho acelerado
return SK_PASS; return SK_PASS;