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.
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.
Demo (asciinema): docs/en/demo.md.
Design: docs/superpowers/specs/2026-11-11-pf-linux-port-design.md
· plan: 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:
./scripts/screencast/record-all.sh # -> out/screencast/*.mp4
Details, per-phase breakdown and the YouTube description text:
docs/en/screencast.md ·
docs/pt-BR/screencast.md
Quick start
Full recipe: docs/en/install.md. Short version
(commands are read from the scripts; a fresh-clone end-to-end run is still
pending):
./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 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).
VM validation lab (Alpine on libvirt): docs/en/vm-lab.md.
Documentação em português: README.pt-BR.md e
docs/pt-BR/.
Layout
module/— kernel sources (ported PF + compat layer; thepfqqdisc lands with M5)tools/— pfctl (static Linux build), pdivert relay source, ABI harness (pflogdnot ported yet)patches/kernel/— Linux core patch set (currently empty; evidence inp1-needs.txt, seedocs/en/patches.md)scripts/— fetch/build/patch/VM automationtests/— VM suite (tests/vm/NN-*.sh, scapy helpers)docs/en/+docs/pt-BR/— full bilingual documentationdocs/superpowers/— design spec + implementation plan
License
Ported OpenBSD code retains its original ISC license and copyright notices. New Linux-side code: ISC.