M1 progress: engine port compiles except pf.c; AF_DIVERT socket family; ifq framework
- compat layer extended through the full BSD API surface pf_ioctl/pf_lb/ pf_if/pf_norm/pf_table/pf_ruleset/radix/md5/sha2 need (all compile): cpumem/counters model, ifaddr/ifg groups, cred view, endian+in6 names, NAT46/64, SipHash24, mbuf_list, frag6 helpers, ip6 forward/checksum, tcp options/FSM names, taskqueue & sysctl shims (documented in docs/porting-notes.md) - pfsrc/divert_sock.c: real BSD divert(4) as runtime-registered PF_DIVERT=32 socket family inside the module (sock_register; NPROTO=AF_MAX=45 -> zero core patches); divert_packet/divert6_packet wired for pf.c - compat/pfk_ifq.c: OpenBSD 8.0 ifq framework with priq back end; hfsc and fq_codel aliases pending M5 (recorded in feature matrix as pending) - design + plan updated for the divert decision (user-requested) - stage-port.sh: single deterministic rename program for headers and .c
This commit is contained in:
1 parent
a84b2c91f3
commit
1fcd7b3046
77 files changed
+28002
-1114
No files matched your search
@@ -124,11 +124,11 @@
|
||||
- [ ] Step 1: implement + port `pf_route/pf_route6` glue; compile.
|
||||
- [ ] Step 2: tests `09-routeto.sh` (tcpdump counts wan vs wan2: rr alternation exact, hash-source deterministic per src; loop-guard: pf0->pf0 route-to with gw=pf0 must not livelock: bounded pkts then block `block loop drop`? use upstream `pf_route` loop detection → drop; assert), `10-dup-fail.sh`; commit.
|
||||
|
||||
### Task 15: divert
|
||||
**Files:** `module/pf/pf_divert_nl.c` (kernel: `netlink_kernel_create(NETLINK_USERSOCK, proto=31? use NETLINK_USERSOCK group id per divert port)`, table port→socket, `divert-to` path: copy skb → nl msg `{cookie, divport, af, ip hdr+payload}`; reinjection path on user `send`: parse → route per original semantics `ip_divert.c` reference (divert-to: re-route to original dst via gw if needed; plain divert tag: re-enter `netif_receive_skb`/local_xmit per 8.0 `pf_send` behavior; drop-after-timeout via per-packet timer default 5s? match upstream: no accept → packet never delivered (copy consumed? original held until accept/timeout then free — mirror OpenBSD: keep, timeout drop).
|
||||
**Interfaces:** `pdivert -p 10000` + rule `pass in divert-to 127.0.0.1 10000`? upstream model: `divert-to` sends to divert socket at **host:port**; ours: netlink port id; document mapping in `docs/en/divert.md`; stats `DIOCBUSYSTATS` unchanged.
|
||||
- [ ] Step 1: implement + tool link already from T8.
|
||||
- [ ] Step 2: test `11-divert.sh`: pdivert on pf0 flips a byte of ping payload → cli receives modified echo-replies; kill pdivert → traffic stops (timeout) not leaks; commit.
|
||||
### Task 15: divert — AF_DIVERT socket family (design §4.4, user-requested)
|
||||
**Files:** `module/pfsrc/divert_sock.c` (kernel-internal PF_DIVERT=32 family via `sock_register`, zero core patches), `tools/pdivert/` (BSD divert(8) workflow over the socket), tests reuse upstream `regress/sys/net/pf_divert` semantics (Perl client adapted to our socket).
|
||||
**Interfaces:** `divert_packet/divert6_packet(mbuf, dir, port)` consumed by pf.c (already wired); userspace ABI: `socket(PF_DIVERT=32, SOCK_RAW, IPPROTO_DIVERT=254)`, `bind(sin_port=divert_port)`, `recvmsg` → raw IP packet + cmsgs (IFINDEX/DIR/TYPE/DST), `sendmsg` → re-inject (divert-to ⇒ local `netif_rx`; tag-divert ⇒ re-route).
|
||||
- [ ] Step 1: kernel self-test (module_param `divert_selftest`): inject synthetic packet → socket recv → send → observed re-injection; no netfilter re-entry loop.
|
||||
- [ ] Step 2: test `11-divert.sh`: pdivert on pf0 flips a byte of ping payload → cli receives modified echo-replies; kill pdivert → traffic stops (no leak); `divert-to 10.0.99.9 10000` cross-host variant; commit.
|
||||
|
||||
### Task 16: ifq + pfq queueing
|
||||
**Files:** `module/ifq/ifq.c ifq.h hfsc.c fq_codel.c` ported (skb-backed via pfk_mbuf), `module/pfq/pfq_qdisc.c` (classful qdisc `pfq`: root=ifq attach; ops: enqueue→`ifq_enqueue(ifq_for_class)`, dequeue loop; classid = queue index from pf rule queue tag), `module/pf/pf_ifq_bridge.c` (DIOCADDQUEUE/GETQUEUES/GETQUEUE/QSTATS + `pf_test` queue assignment + `set queue` default-class + ifq per-iface registry via `pfq_q_enter`), scripts `pf-qdisc.sh` auto-attach on `queue on` detection at DIOCADDQUEUE.
|
||||
|
||||
@@ -139,16 +139,22 @@ priority bits). `DIOCADDQUEUE/DIOCGETQUEUES/DIOCGETQUEUE/DIOCGETQSTATS` (the rea
|
||||
fq_codel** with rate gates (§7); class visibility via `tc -s qdisc show` is a
|
||||
stretch goal, counters via `pfctl` are the gate.
|
||||
|
||||
### 4.4 divert
|
||||
- In-pf action `divert-to host:port` / tag `divert port`: packet copied to
|
||||
userspace divert channel; **channel = kernel netlink** (`NETLINK_USERSOCK` proto)
|
||||
because Linux has no `AF_DIVERT` (in-tree reference logic ported from
|
||||
`sys/netinet/ip_divert.c`; userland `pdivert` tool implements `divert(8)`-style
|
||||
rewrite-loop over the netlink channel; wire format documented; `DIOCBUSYSTATS`
|
||||
etc. unchanged). Diverted flow re-enters via the channel write →
|
||||
`__dev_queue_xmit`/`netif_receive_skb` following ip_divert `divert_output`
|
||||
semantics (re-route via gw neighbor for `divert-to`).
|
||||
- Test parity anchored by upstream `regress/sys/net/pf_divert` semantics.
|
||||
### 4.4 divert — real AF_DIVERT in the kernel (no netlink substitute)
|
||||
OpenBSD's `divert(4)` socket family is ported as a **runtime-registered
|
||||
socket family inside pf.ko**: Linux 7.3 registers protocol families with
|
||||
`sock_register()` and `NPROTO = AF_MAX = 45`, so BSD's `PF_DIVERT = 32`
|
||||
(the unused legacy PF_IUCV slot) fits with **zero core changes**. Implemented
|
||||
in `module/pfsrc/divert_sock.c`: `socket(PF_DIVERT, SOCK_RAW, IPPROTO_DIVERT)`
|
||||
+ `bind(port)` + `recvmsg/sendmsg`, packet metadata via cmsg (ifindex, dir,
|
||||
divert type, original dst). `divert_packet()/divert6_packet()` (called by the
|
||||
ported pf.c) queue to the bound socket; `sendmsg` re-injects with OpenBSD
|
||||
semantics: `PF_DIVERT_TO` → local delivery (`netif_rx` on the recorded
|
||||
interface), plain `divert` tag → re-route (`dst->output`), mirroring
|
||||
`ip_divert.c:divert_output()`. The BSD `divert(8)` workflow (upstream
|
||||
`regress/sys/net/pf_divert`) drives this socket unchanged; our shipped
|
||||
`pdivert` is a thin Linux port. Wire format documented in
|
||||
`docs/en/divert-wireformat.md`. pflog keeps its netlink multicast channel
|
||||
(slot PFLOG_PROTO=1 on `NETLINK_USERSOCK`).
|
||||
|
||||
### 4.5 route-to / dup-to / fail-to
|
||||
`pf_route6`/`pf_route` port: pool selection via `pf_lb.c` (as-is), next-hop
|
||||
|
||||
Reference in new issue
Block a user