summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDaniel Hartmeier <dhartmei@cvs.openbsd.org>2002-06-07 21:25:37 +0000
committerDaniel Hartmeier <dhartmei@cvs.openbsd.org>2002-06-07 21:25:37 +0000
commit87739f251b80651d7bf5e456e0dc04696a638f9b (patch)
tree8a36dbdfa9d45f950ffcc830260b168b4eb45f94 /sys
parent1001fef5168442fee0d557002fbdd7ba550de37a (diff)
Add "(max <number>)" option for "keep/modulate state" to limit the number
of concurrent connections a rule can create. ok frantzen@
Diffstat (limited to 'sys')
-rw-r--r--sys/net/pf.c38
-rw-r--r--sys/net/pfvar.h5
2 files changed, 31 insertions, 12 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c
index 676a54dfebc..a47e9f737fb 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.216 2002/06/07 21:14:02 frantzen Exp $ */
+/* $OpenBSD: pf.c,v 1.217 2002/06/07 21:25:35 dhartmei Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -628,12 +628,12 @@ pf_purge_expired_states(void)
KASSERT(peer->state == cur->state);
RB_REMOVE(pf_state_tree, &tree_lan_ext, peer);
-
/* release NAT resources */
if (STATE_TRANSLATE(cur->state))
pf_put_sport(cur->state->proto,
htons(cur->state->gwy.port));
-
+ if (cur->state->rule.ptr != NULL)
+ cur->state->rule.ptr->states--;
pool_put(&pf_state_pl, cur->state);
pool_put(&pf_tree_pl, cur);
pool_put(&pf_tree_pl, peer);
@@ -3168,16 +3168,20 @@ pf_test_tcp(struct pf_rule **rm, int direction, struct ifnet *ifp,
binat != NULL || rdr != NULL) {
/* create new state */
u_int16_t len;
- struct pf_state *s;
+ struct pf_state *s = NULL;
len = pd->tot_len - off - (th->th_off << 2);
- s = pool_get(&pf_state_pl, PR_NOWAIT);
+ if (*rm == NULL || !(*rm)->max_states ||
+ (*rm)->states < (*rm)->max_states)
+ s = pool_get(&pf_state_pl, PR_NOWAIT);
if (s == NULL) {
if (nport && nat != NULL)
pf_put_sport(IPPROTO_TCP, nport);
REASON_SET(&reason, PFRES_MEMORY);
return (PF_DROP);
}
+ if (*rm != NULL)
+ (*rm)->states++;
s->rule.ptr = *rm;
s->allow_opts = *rm && (*rm)->allow_opts;
@@ -3417,14 +3421,18 @@ pf_test_udp(struct pf_rule **rm, int direction, struct ifnet *ifp,
if ((*rm != NULL && (*rm)->keep_state) || nat != NULL ||
binat != NULL || rdr != NULL) {
/* create new state */
- struct pf_state *s;
+ struct pf_state *s = NULL;
- s = pool_get(&pf_state_pl, PR_NOWAIT);
+ if (*rm == NULL || !(*rm)->max_states ||
+ (*rm)->states < (*rm)->max_states)
+ s = pool_get(&pf_state_pl, PR_NOWAIT);
if (s == NULL) {
if (nport && nat != NULL)
pf_put_sport(IPPROTO_UDP, nport);
return (PF_DROP);
}
+ if (*rm != NULL)
+ (*rm)->states++;
s->rule.ptr = *rm;
s->allow_opts = *rm && (*rm)->allow_opts;
@@ -3682,11 +3690,15 @@ pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp,
if (!state_icmp && ((*rm != NULL && (*rm)->keep_state) ||
nat != NULL || rdr != NULL || binat != NULL)) {
/* create new state */
- struct pf_state *s;
+ struct pf_state *s = NULL;
- s = pool_get(&pf_state_pl, PR_NOWAIT);
+ if (*rm == NULL || !(*rm)->max_states ||
+ (*rm)->states < (*rm)->max_states)
+ s = pool_get(&pf_state_pl, PR_NOWAIT);
if (s == NULL)
return (PF_DROP);
+ if (*rm != NULL)
+ (*rm)->states++;
s->rule.ptr = *rm;
s->allow_opts = *rm && (*rm)->allow_opts;
@@ -3886,11 +3898,15 @@ pf_test_other(struct pf_rule **rm, int direction, struct ifnet *ifp,
if ((*rm != NULL && (*rm)->keep_state) || nat != NULL ||
rdr != NULL || binat != NULL) {
/* create new state */
- struct pf_state *s;
+ struct pf_state *s = NULL;
- s = pool_get(&pf_state_pl, PR_NOWAIT);
+ if (*rm == NULL || !(*rm)->max_states ||
+ (*rm)->states < (*rm)->max_states)
+ s = pool_get(&pf_state_pl, PR_NOWAIT);
if (s == NULL)
return (PF_DROP);
+ if (*rm != NULL)
+ (*rm)->states++;
s->rule.ptr = *rm;
s->allow_opts = *rm && (*rm)->allow_opts;
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index 5f500e768e9..9222f40c498 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfvar.h,v 1.74 2002/06/07 21:14:02 frantzen Exp $ */
+/* $OpenBSD: pfvar.h,v 1.75 2002/06/07 21:25:35 dhartmei Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -244,6 +244,9 @@ struct pf_rule {
struct ifnet *ifp;
struct ifnet *rt_ifp;
+ u_int32_t states;
+ u_int32_t max_states;
+
u_int16_t nr;
u_int16_t return_icmp;
u_int16_t max_mss;