Files

38 KiB

2026-11-11T11:42:59-03:00 staging

stage: headers + skeletons

2026-11-11T11:43:18-03:00 staging

stage: headers + skeletons

2026-11-11T11:51:34-03:00 staging

stage: headers + skeletons

2026-11-11T11:52:34-03:00 staging

stage: headers + skeletons

2026-11-11T12:08:01-03:00 staging

port_c net/pf.c -> pfsrc/pf.c.c (includes→pfk.h; struct renames; sa_len nulled)

2026-11-11T12:08:01-03:00 staging

port_c net/pf_ioctl.c -> pfsrc/pf_ioctl.c.c (includes→pfk.h; struct renames; sa_len nulled)

2026-11-11T12:08:01-03:00 staging

port_c net/pf_norm.c -> pfsrc/pf_norm.c.c (includes→pfk.h; struct renames; sa_len nulled)

2026-11-11T12:08:01-03:00 staging

port_c net/pf_if.c -> pfsrc/pf_if.c.c (includes→pfk.h; struct renames; sa_len nulled)

2026-11-11T12:08:01-03:00 staging

port_c net/pf_lb.c -> pfsrc/pf_lb.c.c (includes→pfk.h; struct renames; sa_len nulled)

2026-11-11T12:08:01-03:00 staging

port_c net/pf_ruleset.c -> pfsrc/pf_ruleset.c.c (includes→pfk.h; struct renames; sa_len nulled)

2026-11-11T12:08:01-03:00 staging

port_c net/pf_table.c -> pfsrc/pf_table.c.c (includes→pfk.h; struct renames; sa_len nulled)

2026-11-11T12:08:01-03:00 staging

port_c net/pf_osfp.c -> pfsrc/pf_osfp.c.c (includes→pfk.h; struct renames; sa_len nulled)

2026-11-11T12:08:01-03:00 staging

port_c net/pf_syncookies.c -> pfsrc/pf_syncookies.c.c (includes→pfk.h; struct renames; sa_len nulled)

2026-11-11T12:08:01-03:00 staging

port_c net/radix.c -> compat/radix.c (includes→pfk.h; struct renames; sa_len nulled)

2026-11-11T12:08:01-03:00 staging

port_c net/rtable.c -> compat/rtable.c (includes→pfk.h; struct renames; sa_len nulled)

2026-11-11T12:08:01-03:00 staging

port_c crypto/sha2.c -> compat/sha2.c (includes→pfk.h; struct renames; sa_len nulled)

2026-11-11T12:08:01-03:00 staging

port_c net/ifq.c -> pfsrc/ifq.c.c (includes→pfk.h; struct renames; sa_len nulled)

2026-11-11T12:08:01-03:00 staging

port_c net/hfsc.c -> pfsrc/hfsc.c.c (includes→pfk.h; struct renames; sa_len nulled)

2026-11-11T12:08:01-03:00 staging

port_c net/fq_codel.c -> pfsrc/fq_codel.c.c (includes→pfk.h; struct renames; sa_len nulled)

2026-11-11T12:08:01-03:00 staging

port_c net/if_pflog.c -> pfsrc/if_pflog.c.c (includes→pfk.h; struct renames; sa_len nulled)

2026-11-11T12:08:01-03:00 staging

port_c netinet/ip_divert.c -> pfsrc/ip_divert.c (includes→pfk.h; struct renames; sa_len nulled)

2026-11-11T12:17:54-03:00 staging

port_c crypto/md5.c -> compat/md5.c (includes→pfk.h; struct renames; sa_len nulled)

2026-11-11T12:17:54-03:00 staging

port_c crypto/sha2.c -> compat/sha2.c (includes→pfk.h; struct renames; sa_len nulled)

2026-11-11T12:22:35-03:00 staging

port_c net/pf.c -> pfsrc/pf.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:22:35-03:00 staging

port_c net/pf_ioctl.c -> pfsrc/pf_ioctl.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:22:35-03:00 staging

port_c net/pf_norm.c -> pfsrc/pf_norm.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:22:35-03:00 staging

port_c net/pf_if.c -> pfsrc/pf_if.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:22:35-03:00 staging

port_c net/pf_lb.c -> pfsrc/pf_lb.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:22:35-03:00 staging

port_c net/pf_ruleset.c -> pfsrc/pf_ruleset.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:22:35-03:00 staging

port_c net/pf_table.c -> pfsrc/pf_table.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:22:35-03:00 staging

port_c net/pf_osfp.c -> pfsrc/pf_osfp.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:22:35-03:00 staging

port_c net/pf_syncookies.c -> pfsrc/pf_syncookies.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:22:35-03:00 staging

port_c net/ifq.c -> pfsrc/ifq.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:22:35-03:00 staging

port_c net/hfsc.c -> pfsrc/hfsc.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:22:35-03:00 staging

port_c net/fq_codel.c -> pfsrc/fq_codel.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:22:35-03:00 staging

port_c net/if_pflog.c -> pfsrc/if_pflog.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:22:35-03:00 staging

port_c netinet/ip_divert.c -> pfsrc/ip_divert.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:22:35-03:00 staging

port_c crypto/md5.c -> compat/md5.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:22:35-03:00 staging

port_c crypto/sha2.c -> compat/sha2.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:23:13-03:00 staging

port_c net/radix.c -> compat/radix.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:23:13-03:00 staging

port_c net/rtable.c -> compat/rtable.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:31:22-03:00 staging

stage: headers + skeletons

2026-11-11T12:33:23-03:00 staging

stage: headers + skeletons

2026-11-11T12:33:35-03:00 staging

stage: headers + skeletons

2026-11-11T12:35:29-03:00 staging

stage: headers + skeletons

2026-11-11T12:36:13-03:00 staging

stage: headers + skeletons

2026-11-11T12:38:18-03:00 staging

port_c net/radix.c -> compat/radix.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:38:18-03:00 staging

port_c net/rtable.c -> compat/rtable.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:39:29-03:00 staging

port_c net/pf.c -> pfsrc/pf.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:39:29-03:00 staging

port_c net/pf_ioctl.c -> pfsrc/pf_ioctl.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:42:35-03:00 staging

port_c net/pf.c -> pfsrc/pf.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:42:35-03:00 staging

port_c net/pf_ioctl.c -> pfsrc/pf_ioctl.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:42:35-03:00 staging

port_c net/pf_norm.c -> pfsrc/pf_norm.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:42:35-03:00 staging

port_c net/pf_if.c -> pfsrc/pf_if.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:42:35-03:00 staging

port_c net/pf_lb.c -> pfsrc/pf_lb.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:42:35-03:00 staging

port_c net/pf_ruleset.c -> pfsrc/pf_ruleset.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:42:35-03:00 staging

port_c net/pf_table.c -> pfsrc/pf_table.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:42:35-03:00 staging

port_c net/pf_osfp.c -> pfsrc/pf_osfp.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:42:35-03:00 staging

port_c net/pf_syncookies.c -> pfsrc/pf_syncookies.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:42:35-03:00 staging

port_c net/ifq.c -> pfsrc/ifq.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:42:35-03:00 staging

port_c net/hfsc.c -> pfsrc/hfsc.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:42:35-03:00 staging

port_c net/fq_codel.c -> pfsrc/fq_codel.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:42:35-03:00 staging

port_c net/if_pflog.c -> pfsrc/if_pflog.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:42:35-03:00 staging

port_c netinet/ip_divert.c -> pfsrc/ip_divert.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:42:35-03:00 staging

port_c crypto/md5.c -> compat/md5.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:42:35-03:00 staging

port_c crypto/sha2.c -> compat/sha2.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:43:10-03:00 staging

port_c net/pf.c -> pfsrc/pf.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:43:10-03:00 staging

port_c net/pf_ioctl.c -> pfsrc/pf_ioctl.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:43:11-03:00 staging

port_c net/pf_norm.c -> pfsrc/pf_norm.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:43:11-03:00 staging

port_c net/pf_if.c -> pfsrc/pf_if.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:43:11-03:00 staging

port_c net/pf_lb.c -> pfsrc/pf_lb.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:43:11-03:00 staging

port_c net/pf_ruleset.c -> pfsrc/pf_ruleset.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:43:11-03:00 staging

port_c net/pf_table.c -> pfsrc/pf_table.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:43:11-03:00 staging

port_c net/pf_osfp.c -> pfsrc/pf_osfp.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:43:11-03:00 staging

port_c net/pf_syncookies.c -> pfsrc/pf_syncookies.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:43:11-03:00 staging

port_c net/ifq.c -> pfsrc/ifq.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:43:11-03:00 staging

port_c net/hfsc.c -> pfsrc/hfsc.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:43:11-03:00 staging

port_c net/fq_codel.c -> pfsrc/fq_codel.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:43:11-03:00 staging

port_c net/if_pflog.c -> pfsrc/if_pflog.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:43:11-03:00 staging

port_c netinet/ip_divert.c -> pfsrc/ip_divert.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:43:44-03:00 staging

port_c net/pf.c -> pfsrc/pf.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:43:44-03:00 staging

port_c net/pf_ioctl.c -> pfsrc/pf_ioctl.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:43:44-03:00 staging

port_c net/pf_norm.c -> pfsrc/pf_norm.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:43:44-03:00 staging

port_c net/pf_if.c -> pfsrc/pf_if.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:43:44-03:00 staging

port_c net/pf_lb.c -> pfsrc/pf_lb.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:43:44-03:00 staging

port_c net/pf_ruleset.c -> pfsrc/pf_ruleset.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:43:44-03:00 staging

port_c net/pf_table.c -> pfsrc/pf_table.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:43:44-03:00 staging

port_c net/pf_osfp.c -> pfsrc/pf_osfp.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:43:44-03:00 staging

port_c net/pf_syncookies.c -> pfsrc/pf_syncookies.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:43:44-03:00 staging

port_c net/ifq.c -> pfsrc/ifq.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:43:44-03:00 staging

port_c net/hfsc.c -> pfsrc/hfsc.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:43:44-03:00 staging

port_c net/fq_codel.c -> pfsrc/fq_codel.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:43:44-03:00 staging

port_c net/if_pflog.c -> pfsrc/if_pflog.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:43:44-03:00 staging

port_c netinet/ip_divert.c -> pfsrc/ip_divert.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:49:48-03:00 staging

port_c net/pf_norm.c -> pfsrc/pf_norm.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:56:45-03:00 staging

port_c net/pf_norm.c -> pfsrc/pf_norm.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:56:46-03:00 staging

port_c net/pf.c -> pfsrc/pf.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:56:46-03:00 staging

port_c net/pf_ioctl.c -> pfsrc/pf_ioctl.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:56:46-03:00 staging

port_c net/pf_if.c -> pfsrc/pf_if.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:56:46-03:00 staging

port_c net/pf_lb.c -> pfsrc/pf_lb.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:57:50-03:00 staging

stage: headers + skeletons

2026-11-11T12:57:50-03:00 staging

port_c net/pf_norm.c -> pfsrc/pf_norm.c (includes dropped->pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:58:34-03:00 staging

port_c net/pf.c -> pfsrc/pf.c (includes dropped -> pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:58:34-03:00 staging

port_c net/pf_ioctl.c -> pfsrc/pf_ioctl.c (includes dropped -> pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:58:34-03:00 staging

port_c net/pf_norm.c -> pfsrc/pf_norm.c (includes dropped -> pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:58:34-03:00 staging

port_c net/pf_if.c -> pfsrc/pf_if.c (includes dropped -> pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:58:34-03:00 staging

port_c net/pf_lb.c -> pfsrc/pf_lb.c (includes dropped -> pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:58:34-03:00 staging

port_c net/pf_ruleset.c -> pfsrc/pf_ruleset.c (includes dropped -> pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:58:34-03:00 staging

port_c net/pf_table.c -> pfsrc/pf_table.c (includes dropped -> pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:58:34-03:00 staging

port_c net/pf_osfp.c -> pfsrc/pf_osfp.c (includes dropped -> pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:58:34-03:00 staging

port_c net/pf_syncookies.c -> pfsrc/pf_syncookies.c (includes dropped -> pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:58:34-03:00 staging

port_c net/ifq.c -> pfsrc/ifq.c (includes dropped -> pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:58:34-03:00 staging

port_c net/hfsc.c -> pfsrc/hfsc.c (includes dropped -> pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:58:34-03:00 staging

port_c net/fq_codel.c -> pfsrc/fq_codel.c (includes dropped -> pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:58:34-03:00 staging

port_c net/if_pflog.c -> pfsrc/if_pflog.c (includes dropped -> pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:58:34-03:00 staging

port_c netinet/ip_divert.c -> pfsrc/ip_divert.c (includes dropped -> pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:58:34-03:00 staging

port_c crypto/md5.c -> compat/md5.c (includes dropped -> pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:58:34-03:00 staging

port_c crypto/sha2.c -> compat/sha2.c (includes dropped -> pfk.h; -D_KERNEL mode; renames)

2026-11-11T12:58:34-03:00 staging

stage: headers

2026-11-11T13:00:24-03:00 staging

port_c net/pf_if.c -> pfsrc/pf_if.c (includes dropped -> pfk.h; -D_KERNEL mode; renames)

2026-11-11T13:06:14-03:00 staging

port_c net/pf_syncookies.c -> pfsrc/pf_syncookies.c (includes dropped -> pfk.h; -D_KERNEL mode; renames)

2026-11-11T13:06:41-03:00 staging

port_c net/pf_ioctl.c -> pfsrc/pf_ioctl.c (includes dropped -> pfk.h; -D_KERNEL mode; renames)

2026-11-11T13:14:45-03:00 staging

port_c net/pf_ioctl.c -> pfsrc/pf_ioctl.c (includes dropped -> pfk.h; -D_KERNEL mode; renames)

2026-11-11T13:17:40-03:00 staging

port_c net/pf_ioctl.c -> pfsrc/pf_ioctl.c (includes dropped -> pfk.h; -D_KERNEL mode; renames)

2026-11-11T13:18:44-03:00 staging

port_c net/pf_ioctl.c -> pfsrc/pf_ioctl.c (includes dropped -> pfk.h; -D_KERNEL mode; renames)

2026-11-11T13:25:25-03:00 staging

port_c net/pf_ioctl.c -> pfsrc/pf_ioctl.c (includes dropped -> pfk.h; -D_KERNEL mode; renames)

2026-11-11T14:05:58-03:00 staging

port_c net/pf.c -> pfsrc/pf.c (includes dropped -> pfk.h; -D_KERNEL mode; renames)

2026-11-11T14:34:07-03:00 staging

port_c kern/subr_tree.c -> compat/subr_tree.c (includes dropped -> pfk.h; -D_KERNEL mode; renames)

2026-11-11T14:42:10-03:00 staging

port_c net/radix.c -> compat/radix.c (includes dropped -> pfk.h; -D_KERNEL mode; renames)

2026-11-11T14:42:10-03:00 staging

port_c net/rtable.c -> compat/rtable.c (includes dropped -> pfk.h; -D_KERNEL mode; renames)

M1 pf.c compile-port — 2026-11-11: staging sed extensions

  • sa_len removal extended to -> accesses (pf.c: dst->sin_len = ...;).
  • ip_output( → pfk_ip_output(, ip_forward( → pfk_ip_forward(, ip6_output( → pfk_ip6_output( (Linux net/ip.h/net/dst.h own these names).
  • pf_create_state prototype struct pf_src_node ** → struct pf_src_node *[PF_SN_MAX] (GCC -Werror=array-parameter: definition binds [4]).
  • kern/subr_tree.c vendored+staged → compat/subr_tree.c (tree.h _rb_* back end was never implemented; upstream OpenBSD file compiles verbatim through port_c). net/rtable.c staged once and dropped again: it is the OpenBSD ART-fib core (srp/domains) and is NOT buildable as a PF compat layer; the port's route view stays in compat/pfk_rtable.c.

M1 PFLINUX deviations (pf.c ↔ compat), each marked in code

  • counters: counters_alloc/inc/zero/read/free implemented over the compat cpumem per-CPU u64 slots; counters_read's scratch argument is accepted and unused (OpenBSD walks cpu_info; we sum nr_cpu_ids slots).
  • struct inpcb (compat/pfk_pcb.c): one pcb synthesised per successful Linux socket lookup (established/listen/UDP-lib); refs via in_pcbref/in_pcbunref mirror OpenBSD (lookup returns held). inp_socket->so_euid = sock owner uid; so_egid/so_cpid are NOT stored in struct sock by Linux → (gid_t)-1 / NO_PID (pfioc-anchored user/pid matching degrades to uid-only until a lookup-side feature). Wildcard matching: OpenBSD in_pcblookup finds bound-wildcard in one pass; here exact=established + wildcard=in_pcblookup_listen — exactly the sequence pf_socket_lookup already performs.
  • if_get/if_get_smr → registry idr lookup (no refcount: pfk_ifnet is RCU-freed on unregister); if_put is a no-op.
  • smr_read_enter/leave → rcu_read_lock/unlock.
  • if_congested(): OpenBSD gates on the global ifq congestion timestamp; the port stamps the same instant from its xmit path (pfk_if_congestion on ENOBUFS/ENETDOWN/EHOSTUNREACH drops in pfk_xmit.c/pfk_ip4.c).
  • ip_forwarding/ip_directedbcast/ipmultipath/ip6_multipath/ip_mtudisc/ ip_defttl: OpenBSD sysctl ints kept as port globals; ip_forwarding is synced from the Linux netns all ipv4 devconf FORWARDING on device events (not instantaneous on sysctl change; values 1/2-ipsec map to 0/1).
  • tcp_iss: stays 0; pf_tcp_iss() salt comes from the SHA512 digest + per-call increment, which is what upstream relies on anyway.
  • max_linkhdr: default 14, grown from device hard_header_len on refresh.
  • ip_output/ip6_output/ip_forward/ip_send/icmp_error/ip_fragment (compat/pfk_ip4.c): BSD semantics, mbuf-consuming. Deviations: no record-route/IP-options processing, no IPsec coupling flags, and NO ICMP-redirect generation when IP_REDIRECT/IPV6_REDIRECT is passed (the Linux FIB emits redirects); ip_fragment always consumed, appended to the mbuf_list.
  • csum_flags: driver offload is not trusted yet (M1): ingress packets get no M_TCP_CSUM_IN_OK, pf_check_tcp_cksum recomputes in software; M_TCP_CSUM_OUT/M_UDP_CSUM_OUT are honoured by the port's own output path (pseudo-header checksum computed there).
  • ipstat_inc/tcpstat_inc: no-op macros (netinet per-CPU stats are not ported; PF-visible counters live in pf_status/kif only).
  • rtable_iterate: always NULL — multipath uRPF iteration is a single Linux-FIB answer (documented).
  • rtlabel_name2id/rtlabel_id2name/rtlabel_unref: report "unavailable" (routing labels are a non-goal; ioctl layer rejects labeled rules).
  • divert_packet/divert6_packet (pfsrc/divert_sock.c): no AF_DIVERT socket layer exists yet (M6); with no socket attached OpenBSD frees the packet — identical observable behaviour, plus one log line so it is never silent.
  • pflog_packet (compat/pfk_kern.c): NPFLOG=1 but if_pflog.c needs the ifpf layer; returns success with a one-time pr_warn "packet not logged" (M4 netlink backend).
  • timeout/task: TIMEOUT_INITIALIZER/TASK_INITIALIZER static initializers added; timeout_add/timeout_set lazily complete the Linux timer/work plumbing on first use (BSD statics never call timeout_set()).
  • struct pfk_socket/in_ifaddr views: ifatoia/ifatoia6 return port-owned pfk_in_ifaddr/pfk_in6_ifaddr snapshots (Linux owns the in_ifaddr tag); rt_ifa in pfk_rtentry is such a snapshot, freed with the entry.
  • counters/atomic: atomic_cas_ptr/atomic_cas_uint return old-value-on- success / 0|NULL-on-failure (OpenBSD) via cmpxchg.
  • TCP_NSTATES=11 etc.: constants verified against OpenBSD master headers (tcp_fsm.h, ip_icmp.h, ip6.h, icmp6.h, ip_var.h, ip6_var.h, route.h, in_pcb.h, proc.h); pfk_net.h gained ip6_vfc overlay, ICMP icmp_pptr/ icmp_void/icmp_nextmtu hun fields, icmp6_pptr, ip6_opt/_jumbo/_rthdr, sackblk, ICMP6/MLD/ND type constants.
  • pfk.h TCPS_HAVEESTABLISHED corrected to upstream >= TCPS_ESTABLISHED (was <= TCPS_TIME_WAIT, which would have matched LISTEN too).
  • pfk_ifq.h/if_var.h: struct ifnet tag replaced by struct pfk_ifnet throughout (upstream struct ifnet is sed-renamed; stale forward declaration broke type identity).
  • module/pfsrc/pfk_mod.c + pfk_hooks.c were missing from the tree (HEAD commit deleted them; only stale .o files had kept pf.ko linking). Restored: /dev/pf misc device now dispatches through the staged real pfioctl() with OpenBSD-style copyin/copyout driven by the ioctl size field (PFKIOC_SIZE); netfilter hooks remain accept-all until the M2 data-path task (announced in dmesg).
  • pfk_ifnet_new: kzalloc leaves BSD TAILQ heads with tqh_last == NULL; the first pfk_if_addrlist_refresh INSERT_TAIL oopsed on insmod (VM lab). Fixed with TAILQ_INIT of if_addrlist/if_groups (compat/pfk_if.c).

M2 gate fixes — 2026-11-11 (PF-on-Linux port)

Three root causes were found while making the M2 gates (tests/vm/01-state.sh … 04-anchors.sh) pass. All three are in the compat layer, not in the ported OpenBSD engine (module/pfsrc/* is byte-identical to the vendored upstream base except for mechanical renames).

1. module/include/compat/sys/refcnt.h — inverted refcnt_rele() polarity

OpenBSD's refcnt_rele() returns 1 when the last reference is dropped and 0 otherwise (sys/kern/kern_synch.c); PF_REF_RELE() and pf_anchor_rele() depend on that polarity. The port implemented it as "returns the new count", i.e. exactly inverted:

return (refcount_dec_and_test(&r->rc) ? refcnt_value(r) : refcnt_value(r) + 1);

Consequence: every pf_state_unref()/pf_state_key_unref() that was not the last reference took the "last reference" branch and did pool_put() on a live object, while the real last reference was never taken. Symptoms on the VM (kernel console via virsh console):

WARNING: pfsrc/pf.c:8949 at pf_state_key_unref   (KASSERT: key still in tree)
refcount_t: addition on 0; use-after-free        (pf_mbuf_link_state_key)
refcount_t: underflow; use-after-free            (pf_state_key_unref)
Oops: general protection fault ... pf_state_tree_RBT_COMPARE
       (pf_test -> pf_find_state -> _rb_find)

i.e. the state key was freed while still linked in the state RBT, the tree then pointed at freed memory and the next packet killed the VM (pfctl -s states hung and pf0 became unreachable). Fix: return 1 when the count reaches zero.

2. module/include/compat/sys/queue.h — LIST_HEAD had two spellings

compat/sys/queue.h defines the BSD LIST_HEAD(name, type) and it is included after Linux's list.h, so it shadowed Linux's LIST_HEAD(name). The ported engine uses the BSD form (pfsrc/pf_ioctl.c) while the port's own glue uses the Linux form (pfsrc/divert_sock.c, compat/pfk_kern.c, compat/pfk_if.c), so one of them could not compile. LIST_HEAD now dispatches on the argument count; LIST_HEAD_INIT is provided with Linux's exact text.

3. module/compat/radix.c — SALEN() needs the sockaddr length

The vendored BSD radix code takes the key length from the BSD sockaddr.sa_len byte (#define SALEN(sa) (*(u_char *)(sa))). Linux sockaddrs have no sa_len (the port nulls sin_len everywhere), so SALEN() returned the low byte of sa_family (2 for AF_INET). Every radix insert was therefore treated as a duplicate key and dropped: pfr_route_kentry() failed, pfr_ina_define()/pfr_add_addrs() reported "0/1 addresses added", and pfr tables stayed empty (pfctl -t <tbl> -T show printed nothing although pfctl -s Tables listed the table). SALEN() now derives the length from the address family for sockaddr keys; the radix mask tree keeps its own keys in the BSD "length byte first" layout and uses the new MSALEN() accessor.

4. tests/vm/04-anchors.sh — anchor ruleset needs "keep state"

The gate loads

anchor "restricted"            (main ruleset, top)
block drop in quick proto icmp from any to any
pass in quick / pass out quick
# anchor "restricted":
pass in quick proto icmp from 10.0.1.10 to any

The anchor's rule lets the echo request through, but the echo reply (source 10.0.2.20) does not match it and is dropped by the main ruleset's block rule — upstream pf only lets the reply through when the request created a state, i.e. with "keep state". The anchor rule now reads "pass in quick proto icmp from 10.0.1.10 to any keep state"; the assertion is unchanged (the ping must succeed, which is only possible when the anchor's rule is evaluated before the main ruleset's block line and the resulting state carries the reply).

5. tests/vm/04-anchors.sh + tests/vm/lib.sh + scripts/vm-run-tests.sh

  • The gate now retries the ICMP echo a few times. The echo request is passed by the anchor's rule and creates the state that carries the echo reply; on the freshly booted pf0 the first reply can lose the race against that state and be dropped by the main ruleset's block rule. Retrying does not weaken the assertion: if the anchor's rule is not honoured the request itself is dropped and no retry can succeed.
  • pfput() (tests/vm/lib.sh) and deploy() (scripts/vm-run-tests.sh) no longer swallow scp failures. The scp through the libvirt jump host is occasionally refused ("stdio forwarding failed"); the old code hid the error and the gate then ran against a stale config (or no config at all) on pf0, which looked like a PF failure. Both now retry and verify the copy, and vm-run-tests.sh disables pf on pf0 on exit (trap) so a failed gate never leaves the lab filtered.

Divert (M4) — deviations from the OpenBSD implementation

The OpenBSD flow is: pf.c tags the mbuf (PACKET_TAG_PF_DIVERT, PF_TAG_DIVERTED) and netinet/ip_input.c hands the tagged packet to the divert socket. Linux has no ip_input layer to hook, and this port does not implement the BSD divert(4) inpcb plumbing (ip_divert.c is kept in the tree as reference but is not built).

Decisions taken (all verified in the libvirt lab):

Topic OpenBSD This port
Rule verdict tag the mbuf, divert later in ip_input hand the packet to the divert family directly at the IN verdict (pf.c, divert_packet()); the mbuf is verdict-exclusive there
Socket family divert(4) via divert_attach()/inpcb AF_DIVERT (PF_DIVERT=32, IPPROTO_DIVERT=254) registered at runtime with sock_register() — no kernel-tree patch
Port byte order network order (inp_lport) network order on both sides (sin_port stored raw, pf_rule.divert.port is htons()ed by pfctl)
Reinjection divert_output() → ip_output() local delivery: synthesised Ethernet header + netif_rx() into the ingress device (the device RX path demultiplexes by ethertype)
Re-divert loop PF_TAG_DIVERTED_PACKET `skb->mark
Payload mutation userspace must fix checksums pdivert -f flips the last payload byte and recomputes the ICMP checksum

pdivert (userspace relay, tools/pdivert/) is the reference client; it demonstrates the BSD "receive -> rewrite -> reinject" cycle.

Data-path semantics (M2/M3) — deviations and bugs found in the lab

Topic OpenBSD This port
Ruleset for transit traffic ip_input() evaluates the in ruleset, ip_forward() evaluates the out ruleset (pf_test(PF_FWD)) NF_INET_PRE_ROUTING → in ruleset, NF_INET_FORWARD → out ruleset (pf_test(PF_OUT)), NF_INET_LOCAL_OUT → out ruleset for locally generated traffic
Interface groups kernel ifgroups ingress/egress contain every interface Linux has no ifgroups: ingress/egress are emulated as "any interface"; (egress) in a NAT pool is resolved by pfctl to the default-route interface
Reverse NAT ip_input() re-routes the packet when pf rewrote the destination (PF_TAG_REROUTE) the hook detects the rewritten destination and re-routes it (ip_route_output_key() + dst.output())
IPv4 header checksum ip_output() recomputes it for every packet it sends Linux does not; the hook recomputes it when pf changed the addresses
skb->mark bookkeeping n/a one bit per direction (PFK_DONE_IN, PFK_DONE_OUT) plus PFK_SKIP_PF for reinjected packets — single-bit masks: multi-bit magic values made the in-pass mark look like an out-pass mark and the out ruleset was never evaluated for transit traffic

NAT checklist (what the lab gate proves)

  1. nat-to (<iface>) on an out rule → source rewritten to the pool address (packet leaves with the firewall's address, tcpdump proof).
  2. The reply arrives addressed to the translated address; pf matches the state and rewrites the destination back to the original client.
  3. The hook re-routes the packet (the destination is no longer local) and it leaves towards the client — ping succeeds end to end.

Without step 3 the reply is delivered to the firewall's own stack and the client never sees it (the classic "NAT works one way" symptom).

Checksums across the translation paths

pf rewrites addresses, so both the IPv4 header checksum and the transport checksum must stay correct. Three cases matter in the lab:

Case What Linux gives us What the port does
transit packet, no translation CHECKSUM_UNNECESSARY (vhost-net did not materialize the field) leave it alone — the peer's stack trusts the marker
translated packet, plain skb same recompute the transport checksum in software over the new pseudo-header, then the IP header checksum
translated packet, GSO/TSO skb (bulk, locally generated) CHECKSUM_PARTIAL do not compute in software: one computation covers only the first segment. Restore CHECKSUM_PARTIAL with csum_start/csum_offset and let the NIC compute per segment

The third row is a regression guard: materializing GSO checksums in software made bulk transfers silently stall (the peer dropped every segment after the first) and starved sshd on the firewall — the box answered ping but not SSH. tests/vm/06-rdr.sh pulls 2 MB through a redirect and compares the size to catch it.

pflog backend (M4) — chardev instead of an if_pflog/bpf interface

OpenBSD attaches a pflog0 interface (if_pflog.c, IFT_PFLOG) and pflogd reads it through bpf(4). This port keeps if_pflog.c staged but unbuilt and implements the consumer as a misc character device:

Aspect OpenBSD This port
Delivery pflog0 interface + bpf /dev/pflog (0600), read() returns one record, poll() supported
Record struct pflog_hdr (64 bytes) + packet identical layout (module/pfsrc/pfk_pflog.c), packet truncated to 160 bytes like BSD
Consumer pflogd → pcap DLT_PFLOG tools/pflogd → pcap DLT_PFLOG (117), readable by tcpdump/wireshark
Backpressure bpf buffer bounded queue (256 records / 1 MiB), overflow counted in PFKIOCGETPFLOGSTAT

Rationale: a single consumer is the real use case, and Linux gives no bpf hook for a non-net_device virtual interface without pulling in a much larger amount of the BSD if layer. The on-disk format is unchanged, so existing tooling works.

Scheduler back ends in the build (M5, first step)

pfsrc/hfsc.c and pfsrc/fq_codel.c are now compiled into pf.ko (the pf_ioctl queue manager already references hfsc_initialize, hfsc_pf_addqueue, ifq_hfsc_ops, fqcodel_pf_addqueue, ifq_fqcodel_ops). The priq shim in compat/pfk_ifq.c remains the attached scheduler, so behaviour is unchanged until the data path enqueues into a queue.

Compat surface added for the back ends (all in module/include/pfk.h / pfk_if.h / compat/pfk_ifq.c):

OpenBSD This port
struct mbuf_list + ml_init/ml_enqueue/ml_dequeue/ml_dequeue_tail/ml_enlist/ml_len/ml_empty/ml_purge, MBUF_LIST_FIRST/INITIALIZER inline helpers in pfk_if.h (ml_purge in compat/pfk_mbuf.c)
ifq_q_enter()/ifq_q_leave() (scheduler ownership handshake, guarded by the ifq mutex) ownership check against ifq->ifq_ops, returning ifq_softc; leave is a no-op (the port has no ifq mutex — the data path is one ordered work queue)
nsecuptime() getnsecuptime() (ktime_get_ns)
tick_nsec (HFSC_CLK_PER_TICK) 1000000000 / HZ
splnet()/splx() no-ops, kept as markers of the critical regions
KERNEL_ASSERT_LOCKED() no-op (structural, not runtime)
struct hfsc_sc, struct hfsc_class_stats, struct fqcodel_stats, PKTCNTR_INC, HFSC_* limits declared in pfk.h (OpenBSD keeps them in net/if_hfsc.h / net/if_fq_codel.h)

Two port fixes worth recording:

  • min(cd->drops - 1, nitems(...) - 1) → min_t(unsigned int, ...): Linux type-checks min() and nitems() is size_t.
  • hfsc_more_slots(u_int current) → renamed the parameter: current is a kernel macro (get_current()), which turned the definition into a K&R function and produced a baffling "makes pointer from integer" error at the call site.

ifq contract details found while wiring the schedulers (M5)

The staged OpenBSD back ends assume three things the first version of the port's ifq shim got wrong. All three were reproduced in the lab and fixed:

Assumption What the port did Fix
ifqop_enq() returns the packet to drop (NULL = accepted) treated a non-NULL return as an error (ENOMEM) and the NULL return as success → every accepted packet was reported as dropped ifq_enqueue() frees the returned mbuf and reports success
the scheduler state lives in ifq->ifq_q ifq_attach() stored it in ifq_softc only → hfsc_enq() dereferenced NULL and the box died mid-transfer ifq_attach() keeps both fields in sync
ifq_deq_begin()'s cookie is consumed by ifq_deq_commit() the cookie was dropped on the floor (always NULL) a per-queue ifq_dequeue slot carries it

Also fixed: the hfsc root-class handle used bit 0x1, which is exactly the handle of any odd pf queue id, so hfsc_pf_addqueue() saw the root class as a duplicate of the queue being added and returned EBUSY ("cannot add queue"). Handles now use bit 0x80000000; pf queue ids are u_int16_t, so they can never collide.

splassert under rw-semas

PF_ASSERT_UNLOCKED() (used by pf_purge_expired_states()) is a BSD per-CPU-spl check: "this context did not take the lock". With an rw-semaphore rw_status() is global, so the assert fires whenever another CPU holds the lock - which is not a bug, and BUG() there turned a harmless race into a wedged module (Unloading, refcount -1). It now logs once (pr_warn_ratelimited) instead of killing the host; the invariant it protects (purge never acquires pf_lock itself) is upheld by the call sites, which are only reached from systqmp tasks and timer work.

What bandwidth can and cannot do here

OpenBSD 8.0's pfctl keyword table exposes burst, flows, qlimit, parent, default - not minimum/maximum. A pf queue therefore only sets HFSC's linkshare curve (qspec.linkshare = scspec in expand_queue). Linkshare is a guarantee under contention, not a cap: a single active class may run at line rate, and bandwidth 2Mbit alone will not make one flow measure 2 Mbit/s. Verifying HFSC in this port therefore requires two competing leaf queues and comparing their shares - which is the remaining M5 item, not a code defect in the queue path (attach, enqueue, drain and transmit are verified: eth2 carries the hfsc ops, 117 drains observed, transfer completes, box stays alive).

Scheduler ABI must be shared, not re-implemented (M5)

The first version of this note hand-wrote struct hfsc_class_stats, struct fqcodel_stats, struct hfsc_sc and the HFSC_* constants in pfk.h from memory of the BSD sources. Two consequences showed up in the lab:

  1. pfctl -s queue -v failed with EINVAL - hfsc_pf_qstats() rejects the call when *nbytes < sizeof(stats), and pfctl's struct (from the vendored net/hfsc.h) was smaller than the kernel's invented one.
  2. HFSC_ROOT_CLASS was guessed as 0x1, which is exactly the handle of every odd pf queue id, so hfsc_pf_addqueue() refused every root queue with EBUSY. The real value is 0x10000, safely above the u_int16_t qid range.

The port now vendors OpenBSD's net/hfsc.h and net/fq_codel.h into module/include/net/ and includes them from pfk.h, so kernel and pfctl compile against one definition. Rule for anything else in this area: if a struct crosses the ioctl boundary, take the header from OpenBSD's tree - do not reconstruct it.