mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-11-07 04:36:52 -10:00
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: 2cef62886d ("pf: convert state retrieval to netlink")
MFC after: 1 week
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D60651
This commit is contained in:
1 file changed
+20
-3
@@ -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
|
||||
|
||||
Reference in new issue
Block a user