git: 3c87acbd4271 - stable/14 - pf: modify pfik_flags atomically
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 28 Oct 2026 20:41:28 UTC
The branch stable/14 has been updated by rcm:
URL: https://cgit.FreeBSD.org/src/commit/?id=3c87acbd427149450db9a800ef5a467272710709
commit 3c87acbd427149450db9a800ef5a467272710709
Author: R. Christian McDonald <rcm@FreeBSD.org>
AuthorDate: 2026-09-30 22:56:22 +0000
Commit: R. Christian McDonald <rcm@FreeBSD.org>
CommitDate: 2026-10-28 20:38:03 +0000
pf: modify pfik_flags atomically
The purge thread sets PFI_IFLAG_REFS on the interfaces that states
refer to without the rules lock, under which the other flags are
changed. The updates can interleave, so that a "set skip on" is lost,
or outlives its removal, until the next ruleset load.
Use atomic operations to modify the flags. In the purge thread, only
write if the flag is not already set.
Reviewed by: kp
Approved by: kp (mentor)
MFC after: 1 week
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D60107
(cherry picked from commit c1241c6e30c792fb514f4689d2ed92ee21d3cf39)
---
sys/netpfil/pf/pf.c | 12 ++++++++++--
sys/netpfil/pf/pf_if.c | 10 +++++-----
2 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index 469087a040e1..7c1f43a8b9bd 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -2459,6 +2459,14 @@ pf_free_state(struct pf_kstate *cur)
pf_counter_u64_add(&V_pf_status.fcounters[FCNT_STATE_REMOVALS], 1);
}
+static inline void
+pf_kkif_mark(struct pfi_kkif *kif)
+{
+
+ if ((atomic_load_int(&kif->pfik_flags) & PFI_IFLAG_REFS) == 0)
+ atomic_set_int(&kif->pfik_flags, PFI_IFLAG_REFS);
+}
+
/*
* Called only from pf_purge_thread(), thus serialized.
*/
@@ -2494,11 +2502,11 @@ relock:
s->nat_rule.ptr->rule_ref |= PFRULE_REFS;
if (s->anchor.ptr != NULL)
s->anchor.ptr->rule_ref |= PFRULE_REFS;
- s->kif->pfik_flags |= PFI_IFLAG_REFS;
+ pf_kkif_mark(s->kif);
SLIST_FOREACH(mrm, &s->match_rules, entry)
mrm->r->rule_ref |= PFRULE_REFS;
if (s->rt_kif)
- s->rt_kif->pfik_flags |= PFI_IFLAG_REFS;
+ pf_kkif_mark(s->rt_kif);
count++;
}
PF_HASHROW_UNLOCK(ih);
diff --git a/sys/netpfil/pf/pf_if.c b/sys/netpfil/pf/pf_if.c
index a5f26b5624bd..0de8013335f0 100644
--- a/sys/netpfil/pf/pf_if.c
+++ b/sys/netpfil/pf/pf_if.c
@@ -380,7 +380,7 @@ pfi_kkif_remove_if_unref(struct pfi_kkif *kif)
RB_REMOVE(pfi_ifhead, &V_pfi_ifs, kif);
- kif->pfik_flags |= PFI_IFLAG_REFS;
+ atomic_set_int(&kif->pfik_flags, PFI_IFLAG_REFS);
mtx_lock(&pfi_unlnkdkifs_mtx);
LIST_INSERT_HEAD(&V_pfi_unlinked_kifs, kif, pfik_list);
@@ -414,7 +414,7 @@ pfi_kkif_purge(void)
LIST_REMOVE(kif, pfik_list);
pf_kkif_free(kif);
} else
- kif->pfik_flags &= ~PFI_IFLAG_REFS;
+ atomic_clear_int(&kif->pfik_flags, PFI_IFLAG_REFS);
}
mtx_unlock(&pfi_unlnkdkifs_mtx);
}
@@ -603,7 +603,7 @@ pfi_kkif_update(struct pfi_kkif *kif)
if (tmpkif == NULL)
continue;
- tmpkif->pfik_flags |= kif->pfik_flags;
+ atomic_set_int(&tmpkif->pfik_flags, kif->pfik_flags);
}
}
@@ -959,7 +959,7 @@ pfi_set_flags(const char *name, int flags)
RB_FOREACH(p, pfi_ifhead, &V_pfi_ifs) {
if (pfi_skip_if(name, p))
continue;
- p->pfik_flags |= flags;
+ atomic_set_int(&p->pfik_flags, flags);
}
NET_EPOCH_EXIT(et);
return (0);
@@ -975,7 +975,7 @@ pfi_clear_flags(const char *name, int flags)
RB_FOREACH_SAFE(p, pfi_ifhead, &V_pfi_ifs, tmp) {
if (pfi_skip_if(name, p))
continue;
- p->pfik_flags &= ~flags;
+ atomic_clear_int(&p->pfik_flags, flags);
if (p->pfik_ifp == NULL && p->pfik_group == NULL &&
p->pfik_flags == 0 && p->pfik_rulerefs == 0) {