Files
pf-linux-port/docs/pt-BR/guide.md
T

6.8 KiB
Raw Blame History

Guia de arquitetura — uma página

English: docs/en/guide.md.

O que este port é

Um port fiel do engine PF do OpenBSD 8.0 rodando dentro do Linux 7.3.4 como um único módulo out-of-tree, pf.ko. Nada é simulado: o casamento de regras, estado, tabelas, normalização e filas é o código do OpenBSD, compilado sob uma camada de compatibilidade; o controle vem do pfctl real, falando a ABI ioctl OpenBSD de verdade por /dev/pf. Existe uma instância global do PF, presa a init_net — exatamente como o OpenBSD tem um único kernel; instâncias por netns estão fora de escopo.

Alvos de build: fontes OpenBSD 8.0 (sha256 fixado em VERSIONS), Linux 7.3.4 (linux-7.3.4), gcc >= 15, bison. O pfvar.h v1.548 é compartilhado bit a bit entre kernel e userland (codificação de ioctl em module/include/pfk.h).

Componentes

Caminho Papel
module/pfsrc/ Arquivos portados do OpenBSD: pf.c (engine), pf_ioctl.c (ABI DIOC*), pf_norm.c (scrub/fragmentos), pf_table.c, pf_ruleset.c, pf_if.c, pf_lb.c (pools/portas NAT), pf_osfp.c, pf_syncookies.c, ifq.c/hfsc.c/fq_codel.c (staged para M5), if_pflog.c + ip_divert.c (referências staged), divert_sock.c (stub de entrada do divert), pfk_mod.c (load/exit, /dev/pf), pfk_hooks.c (caminho de dados netfilter)
module/compat/ Infra Linux sob os fontes em forma BSD: shim mbuf-sobre-sk_buff (pfk_mbuf), glue de kernel (malloc/pools/timeouts/locks, pfk_kern), visão de interfaces e endereços (pfk_if), saída/forward IP com semântica BSD (pfk_ip4, pfk_ip6), busca de sockets (pfk_pcb), API ifq com semântica priq (pfk_ifq), radix/rotas/crypto portados
module/include/ pfk.h (header mestre da compat + codificação _IO* estilo OpenBSD), net/pfvar.h staged, pfk_mbuf.h, pfk_net.h, pfk_if.h
tools/ Build Linux do pfctl do OpenBSD 8.0 (binário único), relay pdivert, verificador de ABI (abitest + make abi), testes de parse offline (make test). Deltas vs upstream: tools/UPSTREAM.md
scripts/ fetch-sources.sh, vendorize.sh, stage-port.sh (staging determinístico), build-kernel.sh, build-module.sh, automação da bancada vm-*.sh
tests/vm/ Gates da suíte em VM: 01-state.sh … 04-anchors.sh + lib.sh; tests/confs/ com rulesets deployados na bancada
patches/kernel/ Conjunto de patches de core — hoje vazio (p1-needs.txt registra por que nenhum export foi necessário); ver patches.md

Caminho de dados (M2, como implementado hoje)

O OpenBSD roda o PF em IPL_NET, em contexto de processo; nossas locks da compat são sleepáveis, então o hook nunca chama pf_test() em softirq. O pacote é furtado (NF_STOLEN) para uma workqueue ordenada (pfk_netisr), o veredito roda em contexto de processo e é aplicado por reinjeção, com marcação por direção em skb->mark para que o pacotão sobrevivente não seja re-enfileirado pelo nosso próprio hook.

                        Linux 7.3.4, módulo pf.ko
  NIC ──► netfilter            (softirq — apenas enfileira)
        PRE_ROUTING  PF_IN ─┐                    ┌─ LOCAL_OUT   PF_OUT
        POST_ROUTING PF_OUT ─┤  NF_STOLEN        ├─ (roda DEPOIS do conntrack)
        LOCAL_IN/FORWARD: pass-through           ┘   POST_ROUTING: NF_IP_PRI_LAST-1
                              │  (ref da skb + kmalloc pfk_pkt;
                              │   falha de alocação ⇒ NF_ACCEPT = fail-open)
                              ▼
                  workqueue pfk_netisr  (contexto de processo)
                              │
                  pfk_m_wrap_skb(skb)──► shim struct mbuf
                              │
                          pf_test(af, dir, ifp, &m)   ◄── o engine real do OpenBSD 8.0:
                              │                          scrub/normalize → lookup de estado
                              │                          → regras/anchors/tabelas/quick
                              │                          → inserção de estado → veredito
                              ▼
        pass ──► mark |= PFK_DONE_IN/OUT ──► reinjeta:  PF_IN: netif_rx() (sobrevivente
                                                      da remontagem entra no stack)
                                                  PF_OUT: skb_dst()->output()
        block/drop ──► kfree_skb()  (+ RST/ICMP de retorno gerados pelo próprio PF)
        fragmento em buffer ──► nossa ref é liberada; pf mantém o sobrevivente (m == NULL)

Plano de controle: /dev/pf (miscdev, modo 0600, escrita condicionada a CAP_NET_ADMIN) → pfk_ioctl_io() copia a estrutura de parâmetros usando o tamanho embutido na codificação _IOR/_IOW OpenBSD e despacha para o pfioctl() portado (pf_ioctl.c) — a ABI DIOC* completa, como upstream. pfctl -e/-f/-s/-t é o mesmo binário do OpenBSD, recompilado.

Filas, divert, pflog — comportamento observável hoje

  • Filas: o pfctl faz o parse de queue/queue on (sintaxe 8.0); no kernel a API ifq é implementada por compat/pfk_ifq.c com semântica priq apenas; o qdisc classful pfq e os back ends HFSC/FQ-CoDel chegam em M5. ifq.c/hfsc.c/fq_codel.c estão staged e prontos para compilar, mas ainda não estão na lista de objetos do módulo.
  • Divert: divert-to/tag divert produzem o veredito PF_DIVERT do PF; divert_packet() (pfsrc/divert_sock.c) hoje descarta o pacote com um pr_warn rate-limited, porque a família de sockets AF_DIVERT ainda não foi instanciada. O relay userspace pdivert existe e espera socket(PF_DIVERT=32, SOCK_RAW, IPPROTO_DIVERT=254).
  • pflog: pflog_packet() retorna sucesso mas não loga nada (um único pr_warn "packet not logged"); if_pflog.c está staged, back end netlink em M4/M5.

Milestones (status por feature em feature-matrix.md)

Milestone Escopo Status (2026-11-11)
M0 repo, scripts, build do kernel, VM liga com kernel próprio concluído
M1 camada de compat, pf.ko carrega, /dev/pf, pfctl -f/-s info concluído
M2 núcleo de filtragem: gates VM de regras/estados/tabelas/anchors em andamento — caminho de dados implementado, gates 01–04 ainda não todos verdes
M3 NAT (nat/rdr/binat), scrub e2e, pflog pendente
M4 route-to/dup-to/fail-to, divert e2e pendente
M5 filas: back ends ifq (hfsc/fq_codel) + qdisc pfq pendente
M6 docs bilíngues completas, patchset arrumado, suíte inteira verde, tags de release em andamento (este conjunto de docs)

Próximas leituras

build.md → vm-lab.md → pf-guide.md → feature-matrix.md → caveats.md.