summaryrefslogtreecommitdiffstats
path: root/sys/netpfil
diff options
context:
space:
mode:
authorglebius <glebius@FreeBSD.org>2013-11-22 19:16:34 +0000
committerglebius <glebius@FreeBSD.org>2013-11-22 19:16:34 +0000
commitc884926273902ab83911a8b89c520ff5a8c58b20 (patch)
tree1f4bd71c6e19b313a7d741b2a54a0cf2b2696737 /sys/netpfil
parent2d853e5460a70e6bb8dad82b6bed486c55f2ace6 (diff)
downloadFreeBSD-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')
-rw-r--r--sys/netpfil/pf/pf.c70
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);
}
OpenPOWER on IntegriCloud