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);

Reply via email to