The branch main has been updated by glebius: URL: https://cgit.FreeBSD.org/src/commit/?id=1a7b74d3125fef50a6d2dcc4442c80457c8d32e1
commit 1a7b74d3125fef50a6d2dcc4442c80457c8d32e1 Author: Gleb Smirnoff <[email protected]> AuthorDate: 2026-01-17 03:57:03 +0000 Commit: Gleb Smirnoff <[email protected]> CommitDate: 2026-01-17 04:09:02 +0000 ipfw: in a vnet destructor use NET_EPOCH_WAIT() The lock grab & drop predates epoch(9) introduction to the network stack and it doesn't provide a true guarantee that all threads that may use ipfw configuration have finished. Also the lock prevented from sleepable operations when freeing the rules. --- sys/netpfil/ipfw/ip_fw2.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sys/netpfil/ipfw/ip_fw2.c b/sys/netpfil/ipfw/ip_fw2.c index 5d5aeb7c2746..7c47a97e4953 100644 --- a/sys/netpfil/ipfw/ip_fw2.c +++ b/sys/netpfil/ipfw/ip_fw2.c @@ -3731,12 +3731,14 @@ vnet_ipfw_uninit(const void *unused) V_ipfw_vnet_ready = 0; /* tell new callers to go away */ /* - * disconnect from ipv4, ipv6, layer2 and sockopt. - * Then grab, release and grab again the WLOCK so we make - * sure the update is propagated and nobody will be in. + * Disconnect from ipv4, ipv6, layer2 and sockopt. pfil(9) hook + * removal is synchronized by the net epoch, but our destructors + * free the memory immediately, thus we need for the epoch sections + * to complete. */ ipfw_detach_hooks(); V_ip_fw_ctl_ptr = NULL; + NET_EPOCH_WAIT(); last = IS_DEFAULT_VNET(curvnet) ? 1 : 0; @@ -3745,12 +3747,10 @@ vnet_ipfw_uninit(const void *unused) ipfw_dyn_uninit(0); /* run the callout_drain */ reap = NULL; - IPFW_WLOCK(chain); for (i = 0; i < chain->n_rules; i++) ipfw_reap_add(chain, &reap, chain->map[i]); free(chain->map, M_IPFW); ipfw_destroy_skipto_cache(chain); - IPFW_WUNLOCK(chain); IPFW_UH_WUNLOCK(chain); ipfw_destroy_tables(chain, last); ipfw_eaction_uninit(chain, last);
