git: 68831d2a2cbb - main - pf: Register the netlink family only while the vnets are set up
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 13 Oct 2026 19:23:01 UTC
The branch main has been updated by rcm:
URL: https://cgit.FreeBSD.org/src/commit/?id=68831d2a2cbb34e8daf24db7e4e15b8c09451f85
commit 68831d2a2cbb34e8daf24db7e4e15b8c09451f85
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-13 19:22:30 +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
---
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 45712f80cad7..174582776fa7 100644
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -7982,8 +7982,6 @@ pf_unload(void *dummy __unused)
}
sx_xunlock(&pf_end_lock);
- pf_nl_unregister();
-
if (pf_dev != NULL)
destroy_dev(pf_dev);
@@ -8011,6 +8009,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)
{
@@ -8019,7 +8037,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