mirror of
https://github.com/lgcosta/pf-linux-port.git
synced 2026-11-15 08:24:45 -03:00
M5: queue gate 15 green (hfsc in the data path, pfctl -s queue works); vendor OpenBSD net/hfsc.h + net/fq_codel.h so kernel and pfctl share the ABI; pflog payload anchored; splassert no longer BUGs
This commit is contained in:
1 parent
4bade69cf9
commit
90c51f43fc
46 files changed
+502
-126
No files matched your search
+22
-20
@@ -111,29 +111,31 @@ lendo `/dev/pflog`; sem ele a fila atinge o limite (256 registros / 1 MiB) e
|
||||
descarta. Nenhum dos dois é mais stub, mas nenhum faz algo sem o consumidor
|
||||
rodar (ver [pf-guide.md](pf-guide.md)).
|
||||
|
||||
### 9. Configurar filas esbarra numa asserção de lock no caminho de purge (aberto)
|
||||
### 9. Filas: caminho verificado; a semântica de modelagem é do HFSC, não um bug
|
||||
|
||||
Carregar uma regra `queue` agora alcança o escalonador (`pfq_alloc` tem sucesso,
|
||||
a disciplina hfsc é criada) e `pf_commit_queues()` é exercitada de ponta a ponta.
|
||||
Dois bugs foram encontrados e corrigidos no caminho: o handle da classe raiz
|
||||
colidia com qids ímpares do pf (`pfq_addqueue` devolvia EBUSY) e a disciplina
|
||||
NULL não era verificada.
|
||||
`15-queue.sh` prova que o caminho de filas funciona de ponta a ponta: a
|
||||
configuração carrega, a disciplina hfsc é anexada à interface, `pfctl -s
|
||||
queue -v` lista as duas classes com estatísticas, um fluxo de 2 MB pela fila
|
||||
completa, e o contador de pacotes da classe avança - o escalonador está mesmo
|
||||
no caminho de dados.
|
||||
|
||||
O que ainda bloqueia as filas: o timer de purge do port pode rodar enquanto um
|
||||
ioctl segura o lock de escrita, e `pf_purge_expired_states()` afirma o contrário:
|
||||
O que o lab não mostra é um *teto de taxa*, e isso é semântica do HFSC, não
|
||||
defeito do port: o `pf.conf` do OpenBSD 8.0 expõe apenas `bandwidth`, que mapeia
|
||||
para a curva **linkshare** do HFSC - garantia quando classes competem, não limite
|
||||
de um fluxo isolado. Não existe palavra-chave `minimum`/`maximum` nesta versão do
|
||||
pfctl (verificado na sua tabela de palavras-chave), logo não há como definir
|
||||
upperlimit pelo pf.conf. Um teste de contenção com duas classes saturadas seria o
|
||||
próximo passo se você quiser asserir sobre share; no enlace virtual de centenas de
|
||||
Mbit do lab, um único fluxo termina antes de acumular dívida de tempo virtual.
|
||||
|
||||
```
|
||||
splassert: pf_purge_expired_states: expected 0, got 2
|
||||
kernel BUG at compat/pfk_kern.c:51
|
||||
```
|
||||
|
||||
O OpenBSD serializa isso com `splnet()`; o port substituiu a camada spl por
|
||||
rw-semáforos e work queue, então a asserção passou a ser uma corrida real em vez
|
||||
de formalidade. Até corrigi-la (liberar o lock em torno da chamada, ou dar ao
|
||||
estado o seu próprio lock como o upstream faz com `pf_state_lock`), um host que
|
||||
configure filas pode travar o módulo em `Unloading`. **Não habilite regras
|
||||
`queue` em host real ainda** — os 14 gates do lab nunca configuram filas, e é
|
||||
por isso que continuam verdes.
|
||||
Bugs encontrados e corrigidos no caminho (detalhes em `docs/porting-notes.md`): a
|
||||
convenção de retorno de `ifqop_enq`, `ifq_q` vs `ifq_softc` (deref de NULL que
|
||||
matava a máquina no meio da transferência), o cookie de dequeue perdido, o
|
||||
handle da classe raiz do hfsc colidindo com qids ímpares do pf, o
|
||||
`DIOCGETQSTATS` falhando porque kernel e pfctl discordavam sobre
|
||||
`struct hfsc_class_stats` (ambos agora usam o `net/hfsc.h` vendorizado), o
|
||||
payload do pflog começando no cabeçalho de transporte, e o `splassert` do caminho
|
||||
de purge que transformava uma corrida benigna em `BUG()`.
|
||||
|
||||
## Desvios da camada de compat (de `docs/porting-notes.md`, registro do M1)
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ Estado em 2026-11-11; evidência por linha: `out/test-logs/`,
|
||||
|---|---|---|---|
|
||||
| Pools de `route-to` (`rr`, `round-robin`, `source-hash`, `hash`), `reply-to`, `dup-to` | `pass in … route-to { 10.0.3.2, 10.0.2.2 } round-robin keep state` | M4 | **`round-robin` e `source-hash` VERIFICADOS em lab** (gate `10-pools.sh`): com dois gateways em dois enlaces, o round-robin usa ambos e o source-hash fixa todo fluxo de uma origem em um único enlace. `dup-to` verificado no gate 08; `reply-to` ainda sem gate. `fail-to` **não existe no OpenBSD 8.0** (removido upstream), então está fora de escopo. |
|
||||
| `divert-to` / tag `divert` | `pass in … divert-to <host> port <n>` | VERIFICADO em lab | **Funciona ponta a ponta.** O módulo registra em runtime a família de sockets `AF_DIVERT` (`PF_DIVERT=32`) — sem patch no kernel. A regra `divert-to` entrega o pacote a essa família; sem listener o pacote é descartado (`divs_noport`, paridade BSD); com `tools/pdivert` rodando o pacote vai ao userspace, é reescrito e reinjetado (verificado com mutação de payload + correção de checksum, ping 0% loss). |
|
||||
| Filas (`queue`, `queue on`, `pfctl -s queue -v`) | `queue root q1 bandwidth 1Mbit; queue on egress all ...` | M5 | **Back ends compilados no `pf.ko`, anexação pendente** — `hfsc.c` e `fq_codel.c` do OpenBSD agora compilam e linkam (157 símbolos do escalonador; `hfsc_initialize`/`hfsc_pf_addqueue`/`fqcodel_pf_addqueue` alcançáveis pelo `pf_ioctl`), e a suíte inteira continua passando com eles dentro. O caminho de dados já pode entregar pacotes a um escalonador anexado (`pf_kifq_input()` + um `ifq_start()` real que drena e transmite), mas as filas **ainda não são seguras para habilitar**: o caminho de purge esbarra numa asserção de lock (ver caveats #9), então nenhuma banda é aplicada e não há gate para isso. |
|
||||
| Filas (`queue`, `queue on`, `pfctl -s queue -v`) | `queue rootq on eth2 bandwidth 10Mbit` + `queue leafq on eth2 bandwidth 2Mbit parent rootq default` | M5 | **VERIFICADO em lab** — gate `15-queue.sh`: a configuração de filas carrega, a disciplina hfsc é anexada à interface, `pfctl -s queue -v` lista as duas classes com estatísticas, um fluxo de 2 MB pela fila completa, e o contador de pacotes da classe avança (o escalonador está no caminho de dados). Note que `bandwidth` é *linkshare* do HFSC - garantia sob contenção, não teto: o pf.conf do OpenBSD 8.0 não tem `minimum`/`maximum`, então um fluxo isolado não é limitado, nem no Linux nem no OpenBSD. |
|
||||
| HFSC | `queue on wan { hfsc … }` | M5 | COMPILES-untested — **fallback priq até o M5**; `pfsrc/hfsc.c` staged (código real do OpenBSD 8.0) mas **fora da lista de objetos** do módulo |
|
||||
| FQ-CoDel | `queue on wan { fq_codel … }` | M5 | COMPILES-untested — igual ao HFSC: staged, não compilado |
|
||||
| Qdisc `pfq` (`tc qdisc … root pfq`) | n/a (glue Linux) | M5 | PENDING-M5 (ainda não existe na árvore) |
|
||||
|
||||
@@ -66,7 +66,7 @@ matriz mudar.
|
||||
| `nat-to`, `rdr-to` | — | **Verificado em lab** (gates `05-nat`, `06-rdr`; este último baixa 2 MB por um redirect e compara byte a byte). `nat-to (egress)` expande o *grupo* de interfaces do OpenBSD; num host multi-NIC prefira a forma explícita `nat-to (<iface>)`. O `binat-to` é expandido pelo pfctl num par `nat-to … static-port` + `rdr-to` (gate `07-binat`). |
|
||||
| `scrub (min-ttl, max-mss, df, random-id)`, `set reassemble` | — | **Verificado em lab** (gate `09-scrub.sh`): `min-ttl` e `max-mss` reescrevem de fato pacotes em trânsito. || `divert-to`, tag `divert` | — | **Verificado em lab** (gate `11-divert`): o pacote é entregue a um socket `AF_DIVERT` (`PF_DIVERT=32`) atendido pelo `tools/pdivert`; sem listener é descartado, exatamente como o `divs_noport` do BSD. |
|
||||
| `route-to`, `dup-to`, `reply-to` | — | **Verificado em lab** (gates `08-routeto.sh`, `13-replyto.sh`): o gateway forçado é usado em vez do egress normal, `dup-to` copia mantendo o fluxo, e `reply-to` empurra as respostas de um fluxo para o enlace do gateway. `fail-to` não é palavra-chave no OpenBSD 8.0 (removido upstream). |
|
||||
| `queue` / `queue on` / `pfctl -s queue` | M5 | Faz parse e carrega. A fila cai no fallback priq da camada `ifq` de compat; **nenhuma limitação de banda acontece até o qdisc `pfq` chegar**. |
|
||||
| `queue` / `queue on` / `pfctl -s queue` | — | **Verificado em lab** (gate `15-queue.sh`): as filas carregam, o hfsc é anexado, `pfctl -s queue -v` mostra as estatísticas das classes e um fluxo de 2 MB pela fila é contado pela classe. `bandwidth` é *garantia sob contenção*, não teto - o pf.conf 8.0 não tem palavra-chave de upperlimit. |
|
||||
| `log`, `log all`, `block log`, `pflogd` | — | **Verificado em lab** (gate `12-pflog`): rode `pflogd /tmp/x.pcap` (lê `/dev/pflog`); o arquivo é um pcap `DLT_PFLOG` (117) legível por tcpdump/wireshark. |
|
||||
| `route-label …` | nunca (não-objetivo) | Rejeitado na camada de ioctl. |
|
||||
| política por container (netns) | fora de escopo | O PF é uma instância global em `init_net`; network namespaces **não** enxergam o PF. |
|
||||
|
||||
Reference in new issue
Block a user