Files
pf-linux-port/README.md
T
lgcosta fe324259c0 Screencasts: seis videos silenciosos 1080p30 da demonstracao
Novo pipeline de video: scripts/screencast/render.py roda uma fase em um pty,
emula o terminal com pyte, gera frames PNG e mux com ffmpeg (H.264,
yuv420p, +faststart, sem trilha de audio). Fallback de encoder: libx264 ->
libopenh264 -> VP9.

Fases (scripts/screencast/phases/, uma sessao real contra o lab por video):
  1. implementacao no kernel - fontes OpenBSD + compat + build limpo do pf.ko
  2. ativacao - insmod, /dev/pf, pfctl -e, pfctl -s info
  3. regras basicas - tabela, anchor, keep state, block drop
  4. roteamento - route-to e reply-to (provado com tcpdump nas 2 interfaces)
  5. balanceamento - pool round-robin, pool source-hash, dup-to
  6. QOS - filas hfsc, pfctl -s queue -v, transferencia de 2 MB pela fila

Os videos ficam versionados em out/screencast/ (.gitignore ajustado para
nao ignorar *.mp4) e o indice/texto de descricao do YouTube em
docs/{en,pt-BR}/screencast.md.

Correcoes na propria demo (encontradas gravando): a acao de uma regra no pf
e pass OU block (nunca os dois); as regras de um anchor vivem em um ruleset
proprio (pfctl -a <anchor> -f); o nc do QOS precisa rodar na VM do servidor,
nao no firewall; o rotulo 'FASE x/6' vem do numero da fase, nao da posicao
na lista de gravacao.
2026-11-12 08:41:41 -03:00

100 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# PF on Linux
Port of the OpenBSD **PF** (packet filter) to **Linux 7.3.4** as an
out-of-tree kernel module — the real PF engine (`pf.c`, `pf_norm.c`,
`pf_table.c`, `pf_lb.c`, … ported from OpenBSD 8.0 sources) driven by the
real OpenBSD `pfctl` over the `/dev/pf` ioctl ABI. (A second module for the
`pfq` qdisc arrives with M5.)
**Status:** the filter core, stateful filtering, tables, anchors, NAT
(`nat-to`/`rdr-to`/`binat-to`), forced routing (`route-to`/`dup-to`), `divert`
and `pflog` are **verified in a real libvirt lab** (14/14 gates green). The
remaining features (queue attachment/pacing, af-to) are still pending — honest per-feature status:
[`docs/en/feature-matrix.md`](docs/en/feature-matrix.md).
Demo (asciinema): [`docs/en/demo.md`](docs/en/demo.md).
Design: [`docs/superpowers/specs/2026-11-11-pf-linux-port-design.md`](docs/superpowers/specs/2026-11-11-pf-linux-port-design.md)
· plan: [`docs/superpowers/plans/2026-11-11-pf-linux-port.md`](docs/superpowers/plans/2026-11-11-pf-linux-port.md).
## Milestones
| Milestone | Scope | Status (2026-11-11) |
|---|---|---|
| M0 | repo, scripts, kernel build, VM boots the custom kernel | done |
| M1 | compat layer, `pf.ko` loads, `/dev/pf`, `pfctl -f` / `-s info` | done |
| M2 | filter core: rules/states/tables/anchors, VM gates 01–04 | **done** — gates 01/02/03/04 green |
| M3 | NAT (`nat-to`/`rdr-to`/`binat-to`), scrub | **done** — gates 05/06/07/09 (incl. 2 MB integrity through a redirect, min-ttl/max-mss measured) |
| M4 | route-to/dup-to/reply-to, divert e2e, pflog | **done** — divert (11), pflog (12), route-to/dup-to (08), pools (10), reply-to (13) verified |
| M5 | queues: HFSC back end in the data path | **done (mechanical)** — gate 15: queues load, hfsc attaches, `pfctl -s queue -v` reports class stats, a 2 MB queued flow is counted by the class. `bandwidth` = HFSC linkshare (guarantee, not cap; 8.0 has no upperlimit syntax) |
| M6 | docs complete, patchset tidy, full suite green, tagged release | **done** — docs EN+PT-BR, 11/11 suite green, tagged (v0.5.0) |
## What you get (planned)
| Area | Feature |
|---|---|
| Filtering | rules, anchors, quick, `match`/`block`(drop/return/return-rst)/`pass`, `keep state`, syncookies |
| State/Tables | stateful firewall engine, `pfr` tables (radix + hash, `pfctl -t`) |
| NAT | `nat-to` (port pools, sticky-port, static-port), `rdr-to`, `binat-to` |
| Scrub | fragment reassembly, overlap drop, `min-ttl`/`max-mss`/`df`/`no-df`, `set reassemble` |
| QoS (ALTQ successor) | `queue`/`queue on` with OpenBSD 8.0 `ifq` schedulers: **HFSC verified in the data path** (gate 15), priq default, FQ-CoDel compiled; `pfctl -s queue -v` works |
| Divert | `divert-to` / `divert` tag + `pdivert` relay over an in-module `PF_DIVERT` socket family (verified: packet to userspace and back) |
| Route | `route-to`/`dup-to`/`reply-to` + pools (`round-robin`, `source-hash`) verified (`fail-to` no longer exists in OpenBSD 8.0) |
| Logging | `pflogd` via `/dev/pflog` (DLT_PFLOG pcap, OpenBSD record layout) — verified |
| Control | `/dev/pf` (0600), OpenBSD 8.0 ioctl ABI, Linux build of `pfctl` (single binary) |
Not in scope: `pfsync`/CARP failover, IPsec/pfkey, `ftp-proxy`, per-netns PF
instances, classic-ALTQ-only schedulers (cbq/wfq/red — removed upstream before
OpenBSD 8.0).
## Screencasts
Six silent 1080p30 MP4 screencasts of the lab — implementation in the kernel,
activation, basic rules, routing, balancing and QOS — each one a real session
against the Alpine VMs:
```sh
./scripts/screencast/record-all.sh # -> out/screencast/*.mp4
```
Details, per-phase breakdown and the YouTube description text:
[`docs/en/screencast.md`](docs/en/screencast.md) ·
[`docs/pt-BR/screencast.md`](docs/pt-BR/screencast.md)
## Quick start
Full recipe: [`docs/en/install.md`](docs/en/install.md). Short version
(commands are read from the scripts; a fresh-clone end-to-end run is still
pending):
```sh
./scripts/fetch-sources.sh # OpenBSD 8.0 sources (C3SL mirror, sha256-pinned)
./scripts/vendorize.sh # stage the pristine files we port
./scripts/build-kernel.sh # kernel 7.3.4: bzImage + modules_prepare (export patch: none needed)
./scripts/build-module.sh # -> module/pf.ko
make -C tools # -> tools/out/pfctl (static), ABI harness
sudo insmod module/pf.ko # /dev/pf (0600) + netfilter hooks
sudo pfctl -f /etc/pf.conf && sudo pfctl -e
```
Read [`docs/en/pf-guide.md`](docs/en/pf-guide.md) **before** enabling PF on a
path you need: only the M2 filter core is gated today; NAT/scrub/queues/
divert/pflog are not usable yet ([`docs/en/feature-matrix.md`](docs/en/feature-matrix.md)).
VM validation lab (Alpine on libvirt): [`docs/en/vm-lab.md`](docs/en/vm-lab.md).
Documentação em português: [`README.pt-BR.md`](README.pt-BR.md) e
[`docs/pt-BR/`](docs/pt-BR/README.md).
## Layout
- `module/` — kernel sources (ported PF + compat layer; the `pfq` qdisc lands with M5)
- `tools/` — pfctl (static Linux build), pdivert relay source, ABI harness (`pflogd` not ported yet)
- `patches/kernel/` — Linux core patch set (currently empty; evidence in `p1-needs.txt`, see `docs/en/patches.md`)
- `scripts/` — fetch/build/patch/VM automation
- `tests/` — VM suite (`tests/vm/NN-*.sh`, scapy helpers)
- `docs/en/` + `docs/pt-BR/` — full bilingual documentation
- `docs/superpowers/` — design spec + implementation plan
## License
Ported OpenBSD code retains its original [ISC license and copyright notices](LICENSE).
New Linux-side code: ISC.