Date: Sun, 9 Jul 2017 17:56:39 +0000 (UTC) From: Kristof Provost <kp@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r320848 - head/sys/netpfil/pf Message-ID: <201707091756.v69HudGL021335@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kp Date: Sun Jul 9 17:56:39 2017 New Revision: 320848 URL: https://svnweb.freebsd.org/changeset/base/320848 Log: pf: Fix vnet purging pf_purge_thread() breaks up the work of iterating all states (in pf_purge_expired_states()) and tracks progress in the idx variable. If multiple vnets exist this results in pf_purge_thread() only calling pf_purge_expired_states() for part of the states (the first part of the first vnet, second part of the second vnet and so on). Combined with the mark-and-sweep approach to cleaning up old rules (in V_pf_unlinked_rules) that resulted in pf freeing rules that were still referenced by states. This in turn caused panics when pf_state_expires() encounters that state and attempts to access the rule. We need to track the progress per vnet, not globally, so idx is moved into a per-vnet V_pf_purge_idx. PR: 219251 Sponsored by: Hackathon Essen 2017 Modified: head/sys/netpfil/pf/pf.c Modified: head/sys/netpfil/pf/pf.c ============================================================================== --- head/sys/netpfil/pf/pf.c Sun Jul 9 17:05:48 2017 (r320847) +++ head/sys/netpfil/pf/pf.c Sun Jul 9 17:56:39 2017 (r320848) @@ -132,6 +132,9 @@ VNET_DEFINE(int, pf_tcp_iss_off); VNET_DECLARE(int, pf_vnet_active); #define V_pf_vnet_active VNET(pf_vnet_active) +static VNET_DEFINE(uint32_t, pf_purge_idx); +#define V_pf_purge_idx VNET(pf_purge_idx) + /* * Queue for pf_intr() sends. */ @@ -1427,7 +1430,6 @@ void pf_purge_thread(void *unused __unused) { VNET_ITERATOR_DECL(vnet_iter); - u_int idx = 0; sx_xlock(&pf_end_lock); while (pf_end_threads == 0) { @@ -1448,14 +1450,15 @@ pf_purge_thread(void *unused __unused) * Process 1/interval fraction of the state * table every run. */ - idx = pf_purge_expired_states(idx, pf_hashmask / + V_pf_purge_idx = + pf_purge_expired_states(V_pf_purge_idx, pf_hashmask / (V_pf_default_rule.timeout[PFTM_INTERVAL] * 10)); /* * Purge other expired types every * PFTM_INTERVAL seconds. */ - if (idx == 0) { + if (V_pf_purge_idx == 0) { /* * Order is important: * - states and src nodes reference rules
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201707091756.v69HudGL021335>