diff options
author | glebius <glebius@FreeBSD.org> | 2013-11-22 19:16:34 +0000 |
---|---|---|
committer | glebius <glebius@FreeBSD.org> | 2013-11-22 19:16:34 +0000 |
commit | c884926273902ab83911a8b89c520ff5a8c58b20 (patch) | |
tree | 1f4bd71c6e19b313a7d741b2a54a0cf2b2696737 /sys/netpfil/pf | |
parent | 2d853e5460a70e6bb8dad82b6bed486c55f2ace6 (diff) | |
download | FreeBSD-src-c884926273902ab83911a8b89c520ff5a8c58b20.zip FreeBSD-src-c884926273902ab83911a8b89c520ff5a8c58b20.tar.gz |
To support upcoming changes change internal API for source node handling:
- Removed pf_remove_src_node().
- Introduce pf_unlink_src_node() and pf_unlink_src_node_locked().
These function do not proceed with freeing of a node, just disconnect
it from storage.
- New function pf_free_src_nodes() works on a list of previously
disconnected nodes and frees them.
- Utilize new API in pf_purge_expired_src_nodes().
In collaboration with: Kajetan Staszkiewicz <kajetan.staszkiewicz innogames.de>
Sponsored by: InnoGames GmbH
Sponsored by: Nginx, Inc.
Diffstat (limited to 'sys/netpfil/pf')
-rw-r--r-- | sys/netpfil/pf/pf.c | 70 |
1 files changed, 54 insertions, 16 deletions
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 30c726b..b2e3788 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -681,20 +681,54 @@ pf_insert_src_node(struct pf_src_node **sn, struct pf_rule *rule, return (0); } -static void -pf_remove_src_node(struct pf_src_node *src) +void +pf_unlink_src_node_locked(struct pf_src_node *src) { +#ifdef INVARIANTS struct pf_srchash *sh; sh = &V_pf_srchash[pf_hashsrc(&src->addr, src->af)]; - PF_HASHROW_LOCK(sh); + PF_HASHROW_ASSERT(sh); +#endif LIST_REMOVE(src, entry); - PF_HASHROW_UNLOCK(sh); - + if (src->rule.ptr) + src->rule.ptr->src_nodes--; V_pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; V_pf_status.src_nodes--; +} - uma_zfree(V_pf_sources_z, src); +void +pf_unlink_src_node(struct pf_src_node *src) +{ + struct pf_srchash *sh; + + sh = &V_pf_srchash[pf_hashsrc(&src->addr, src->af)]; + PF_HASHROW_LOCK(sh); + pf_unlink_src_node_locked(src); + PF_HASHROW_UNLOCK(sh); +} + +static void +pf_free_src_node(struct pf_src_node *sn) +{ + + KASSERT(sn->states == 0, ("%s: %p has refs", __func__, sn)); + LIST_REMOVE(sn, entry); + uma_zfree(V_pf_sources_z, sn); +} + +u_int +pf_free_src_nodes(struct pf_src_node_list *head) +{ + struct pf_src_node *sn, *tmp; + u_int count = 0; + + LIST_FOREACH_SAFE(sn, head, entry, tmp) { + pf_free_src_node(sn); + count++; + } + + return (count); } /* Data storage structures initialization. */ @@ -1464,24 +1498,24 @@ pf_state_expires(const struct pf_state *state) void pf_purge_expired_src_nodes() { + struct pf_src_node_list freelist; struct pf_srchash *sh; struct pf_src_node *cur, *next; int i; + LIST_INIT(&freelist); for (i = 0, sh = V_pf_srchash; i <= V_pf_srchashmask; i++, sh++) { PF_HASHROW_LOCK(sh); LIST_FOREACH_SAFE(cur, &sh->nodes, entry, next) if (cur->states == 0 && cur->expire <= time_uptime) { - if (cur->rule.ptr != NULL) - cur->rule.ptr->src_nodes--; - LIST_REMOVE(cur, entry); - V_pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; - V_pf_status.src_nodes--; - uma_zfree(V_pf_sources_z, cur); + pf_unlink_src_node_locked(cur); + LIST_INSERT_HEAD(&freelist, cur, entry); } else if (cur->rule.ptr != NULL) cur->rule.ptr->rule_flag |= PFRULE_REFS; PF_HASHROW_UNLOCK(sh); } + + pf_free_src_nodes(&freelist); } static void @@ -3771,11 +3805,15 @@ csfailed: if (nk != NULL) uma_zfree(V_pf_state_key_z, nk); - if (sn != NULL && sn->states == 0 && sn->expire == 0) - pf_remove_src_node(sn); + if (sn != NULL && sn->states == 0 && sn->expire == 0) { + pf_unlink_src_node(sn); + pf_free_src_node(sn); + } - if (nsn != sn && nsn != NULL && nsn->states == 0 && nsn->expire == 0) - pf_remove_src_node(nsn); + if (nsn != sn && nsn != NULL && nsn->states == 0 && nsn->expire == 0) { + pf_unlink_src_node(nsn); + pf_free_src_node(nsn); + } return (PF_DROP); } |