diff options
| author | Gleb Smirnoff <glebius@FreeBSD.org> | 2026-01-26 23:05:17 +0000 |
|---|---|---|
| committer | Gleb Smirnoff <glebius@FreeBSD.org> | 2026-01-26 23:05:17 +0000 |
| commit | d1a8f1a62f31779e1902b856b44249b198178fc9 (patch) | |
| tree | 23df2ae8bcf9c21dbaab3b9c71e287fee4fe0796 | |
| parent | 31e5decb18a6633f5137848b5734310b41fc3bdc (diff) | |
ipfw: don't use the upper half lock to walk dynamic states buckets
The lock is sleepable and we can't grab it in dyn_tick(). Use the
individual bucket locks instead.
Fixes: e3caa360d5d0a73af0de1d293d5b8ff6e900ceb4
| -rw-r--r-- | sys/netpfil/ipfw/ip_fw_dynamic.c | 18 |
1 files changed, 4 insertions, 14 deletions
diff --git a/sys/netpfil/ipfw/ip_fw_dynamic.c b/sys/netpfil/ipfw/ip_fw_dynamic.c index 99fd72de5e0a..d2bf4f4fc899 100644 --- a/sys/netpfil/ipfw/ip_fw_dynamic.c +++ b/sys/netpfil/ipfw/ip_fw_dynamic.c @@ -2498,13 +2498,8 @@ dyn_send_keepalive_ipv4(struct ip_fw_chain *chain) uint32_t bucket; mbufq_init(&q, INT_MAX); - IPFW_UH_RLOCK(chain); - /* - * It is safe to not use hazard pointer and just do lockless - * access to the lists, because states entries can not be deleted - * while we hold IPFW_UH_RLOCK. - */ for (bucket = 0; bucket < V_curr_dyn_buckets; bucket++) { + DYN_BUCKET_LOCK(bucket); CK_SLIST_FOREACH(s, &V_dyn_ipv4[bucket], entry) { /* * Only established TCP connections that will @@ -2517,8 +2512,8 @@ dyn_send_keepalive_ipv4(struct ip_fw_chain *chain) continue; dyn_enqueue_keepalive_ipv4(&q, s); } + DYN_BUCKET_UNLOCK(bucket); } - IPFW_UH_RUNLOCK(chain); while ((m = mbufq_dequeue(&q)) != NULL) ip_output(m, NULL, NULL, 0, NULL, NULL); } @@ -2605,13 +2600,8 @@ dyn_send_keepalive_ipv6(struct ip_fw_chain *chain) uint32_t bucket; mbufq_init(&q, INT_MAX); - IPFW_UH_RLOCK(chain); - /* - * It is safe to not use hazard pointer and just do lockless - * access to the lists, because states entries can not be deleted - * while we hold IPFW_UH_RLOCK. - */ for (bucket = 0; bucket < V_curr_dyn_buckets; bucket++) { + DYN_BUCKET_LOCK(bucket); CK_SLIST_FOREACH(s, &V_dyn_ipv6[bucket], entry) { /* * Only established TCP connections that will @@ -2624,8 +2614,8 @@ dyn_send_keepalive_ipv6(struct ip_fw_chain *chain) continue; dyn_enqueue_keepalive_ipv6(&q, s); } + DYN_BUCKET_UNLOCK(bucket); } - IPFW_UH_RUNLOCK(chain); while ((m = mbufq_dequeue(&q)) != NULL) ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL); } |
