git: 0dc07bbc7769 - stable/15 - pf: Register the netlink family only while the vnets are set up
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 28 Oct 2026 20:36:00 UTC
The branch stable/15 has been updated by rcm:
URL: https://cgit.FreeBSD.org/src/commit/?id=0dc07bbc7769a885d188e2137bfc9def112ded0b
commit 0dc07bbc7769a885d188e2137bfc9def112ded0b
Author: R. Christian McDonald <rcm@FreeBSD.org>
AuthorDate: 2026-10-13 19:22:30 +0000
Commit: R. Christian McDonald <rcm@FreeBSD.org>
CommitDate: 2026-10-28 20:34:17 +0000
pf: Register the netlink family only while the vnets are set up
pf_modevent() registers the generic netlink family at MOD_LOAD, before
vnet_pf_init() has set up the state hashes and locks the handlers use,
and pf_unload() unregisters it after vnet_pf_uninit() has torn them
down. Sending PFNL_CMD_GETSTATES while pf loads or unloads panics in
pf_handle_getstates() on a NULL or freed V_pf_idhash.
Register the family from a SYSINIT ordered after vnet_pf_init(), and
unregister it from the matching SYSUNINIT, before vnet_pf_uninit().
Reviewed by: kp
Fixes: 2cef62886dc7 ("pf: convert state retrieval to netlink")
MFC after: 1 week
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D60651
(cherry picked from commit 68831d2a2cbb34e8daf24db7e4e15b8c09451f85)
---
sys/netpfil/pf/pf_ioctl.c | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
index 0ba1f910bf2a..5260ced4088c 100644
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -7196,8 +7196,6 @@ pf_unload(void *dummy __unused)
}
sx_xunlock(&pf_end_lock);
- pf_nl_unregister();
-
if (pf_dev != NULL)
destroy_dev(pf_dev);
@@ -7225,6 +7223,26 @@ SYSUNINIT(pf_unload, SI_SUB_PROTO_FIREWALL, SI_ORDER_SECOND, pf_unload, NULL);
VNET_SYSUNINIT(vnet_pf_uninit, SI_SUB_PROTO_FIREWALL, SI_ORDER_THIRD,
vnet_pf_uninit, NULL);
+/*
+ * The netlink handlers use the per-vnet state: register them after
+ * vnet_pf_init() and unregister them before vnet_pf_uninit().
+ */
+static void
+pf_nl_init(void *unused __unused)
+{
+
+ pf_nl_register();
+}
+SYSINIT(pf_nl, SI_SUB_PROTO_FIREWALL, SI_ORDER_FOURTH, pf_nl_init, NULL);
+
+static void
+pf_nl_uninit(void *unused __unused)
+{
+
+ pf_nl_unregister();
+}
+SYSUNINIT(pf_nl, SI_SUB_PROTO_FIREWALL, SI_ORDER_FOURTH, pf_nl_uninit, NULL);
+
static int
pf_modevent(module_t mod, int type, void *data)
{
@@ -7233,7 +7251,6 @@ pf_modevent(module_t mod, int type, void *data)
switch(type) {
case MOD_LOAD:
error = pf_load();
- pf_nl_register();
break;
case MOD_UNLOAD:
/* Handled in SYSUNINIT(pf_unload) to ensure it's done after