summaryrefslogtreecommitdiff
path: root/sys/net/pf.c
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2004-04-17 00:13:37 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2004-04-17 00:13:37 +0000
commitcf3b837b4f2865a0c44b7900357c645e3c6d7ccd (patch)
tree2d5f45d38b61959c55a936fca3a6516985f81030 /sys/net/pf.c
parent3747d407a8cbf26aa887a81515ca063e7908ce58 (diff)
when the input queue congestion flag is set stop evaluating the ruleset
and block unconditionally. when the inout queue is full, newly arriving packets are dropped anyway, and while the input queue is full we obviously have a CPU laod problem. with this change, we allow the machine to recover gracefully, dropping a few packets fast instead of a lot slowly over a long time while processing rather old stuff in the input queue, giving somebody a chance to log in on the console and fix stuff instead of going completely unresponsive, and as a nice side effect, let established connections alone. ok kjc@ markus@ beck@
Diffstat (limited to 'sys/net/pf.c')
-rw-r--r--sys/net/pf.c59
1 files changed, 42 insertions, 17 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c
index 53f5a5914b5..b4eaa47f7c5 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.434 2004/04/05 08:19:49 dhartmei Exp $ */
+/* $OpenBSD: pf.c,v 1.435 2004/04/17 00:13:36 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -144,19 +144,19 @@ struct pf_rule *pf_get_translation(struct pf_pdesc *, struct mbuf *,
int pf_test_tcp(struct pf_rule **, struct pf_state **,
int, struct pfi_kif *, struct mbuf *, int,
void *, struct pf_pdesc *, struct pf_rule **,
- struct pf_ruleset **);
+ struct pf_ruleset **, struct ifqueue *);
int pf_test_udp(struct pf_rule **, struct pf_state **,
int, struct pfi_kif *, struct mbuf *, int,
void *, struct pf_pdesc *, struct pf_rule **,
- struct pf_ruleset **);
+ struct pf_ruleset **, struct ifqueue *);
int pf_test_icmp(struct pf_rule **, struct pf_state **,
int, struct pfi_kif *, struct mbuf *, int,
void *, struct pf_pdesc *, struct pf_rule **,
- struct pf_ruleset **);
+ struct pf_ruleset **, struct ifqueue *);
int pf_test_other(struct pf_rule **, struct pf_state **,
int, struct pfi_kif *, struct mbuf *, int, void *,
struct pf_pdesc *, struct pf_rule **,
- struct pf_ruleset **);
+ struct pf_ruleset **, struct ifqueue *);
int pf_test_fragment(struct pf_rule **, int,
struct pfi_kif *, struct mbuf *, void *,
struct pf_pdesc *, struct pf_rule **,
@@ -205,6 +205,7 @@ int pf_addr_wrap_neq(struct pf_addr_wrap *,
static int pf_add_mbuf_tag(struct mbuf *, u_int);
struct pf_state *pf_find_state_recurse(struct pfi_kif *,
struct pf_state *, u_int8_t);
+int pf_check_congestion(struct ifqueue *);
struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX] = {
{ &pf_state_pl, PFSTATE_HIWAT },
@@ -2411,7 +2412,8 @@ pf_set_rt_ifp(struct pf_state *s, struct pf_addr *saddr)
int
pf_test_tcp(struct pf_rule **rm, struct pf_state **sm, int direction,
struct pfi_kif *kif, struct mbuf *m, int off, void *h,
- struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm)
+ struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm,
+ struct ifqueue *ifq)
{
struct pf_rule *nr = NULL;
struct pf_addr *saddr = pd->src, *daddr = pd->dst;
@@ -2430,6 +2432,9 @@ pf_test_tcp(struct pf_rule **rm, struct pf_state **sm, int direction,
int tag = -1;
u_int16_t mss = tcp_mssdflt;
+ if (pf_check_congestion(ifq))
+ return (PF_DROP);
+
r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
if (direction == PF_OUT) {
@@ -2766,7 +2771,8 @@ cleanup:
int
pf_test_udp(struct pf_rule **rm, struct pf_state **sm, int direction,
struct pfi_kif *kif, struct mbuf *m, int off, void *h,
- struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm)
+ struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm,
+ struct ifqueue *ifq)
{
struct pf_rule *nr = NULL;
struct pf_addr *saddr = pd->src, *daddr = pd->dst;
@@ -2784,6 +2790,9 @@ pf_test_udp(struct pf_rule **rm, struct pf_state **sm, int direction,
struct pf_tag *pftag = NULL;
int tag = -1;
+ if (pf_check_congestion(ifq))
+ return (PF_DROP);
+
r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
if (direction == PF_OUT) {
@@ -3029,7 +3038,8 @@ cleanup:
int
pf_test_icmp(struct pf_rule **rm, struct pf_state **sm, int direction,
struct pfi_kif *kif, struct mbuf *m, int off, void *h,
- struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm)
+ struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm,
+ struct ifqueue *ifq)
{
struct pf_rule *nr = NULL;
struct pf_addr *saddr = pd->src, *daddr = pd->dst;
@@ -3047,6 +3057,9 @@ pf_test_icmp(struct pf_rule **rm, struct pf_state **sm, int direction,
int rewrite = 0;
#endif /* INET6 */
+ if (pf_check_congestion(ifq))
+ return (PF_DROP);
+
switch (pd->proto) {
#ifdef INET
case IPPROTO_ICMP:
@@ -3307,7 +3320,7 @@ cleanup:
int
pf_test_other(struct pf_rule **rm, struct pf_state **sm, int direction,
struct pfi_kif *kif, struct mbuf *m, int off, void *h, struct pf_pdesc *pd,
- struct pf_rule **am, struct pf_ruleset **rsm)
+ struct pf_rule **am, struct pf_ruleset **rsm, struct ifqueue *ifq)
{
struct pf_rule *nr = NULL;
struct pf_rule *r, *a = NULL;
@@ -3319,6 +3332,9 @@ pf_test_other(struct pf_rule **rm, struct pf_state **sm, int direction,
struct pf_tag *pftag = NULL;
int tag = -1;
+ if (pf_check_congestion(ifq))
+ return (PF_DROP);
+
r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
if (direction == PF_OUT) {
@@ -5335,7 +5351,7 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0)
log = s->log;
} else if (s == NULL)
action = pf_test_tcp(&r, &s, dir, kif,
- m, off, h, &pd, &a, &ruleset);
+ m, off, h, &pd, &a, &ruleset, &ipintrq);
break;
}
@@ -5369,7 +5385,7 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0)
log = s->log;
} else if (s == NULL)
action = pf_test_udp(&r, &s, dir, kif,
- m, off, h, &pd, &a, &ruleset);
+ m, off, h, &pd, &a, &ruleset, &ipintrq);
break;
}
@@ -5397,7 +5413,7 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0)
log = s->log;
} else if (s == NULL)
action = pf_test_icmp(&r, &s, dir, kif,
- m, off, h, &pd, &a, &ruleset);
+ m, off, h, &pd, &a, &ruleset, &ipintrq);
break;
}
@@ -5412,7 +5428,7 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0)
log = s->log;
} else if (s == NULL)
action = pf_test_other(&r, &s, dir, kif, m, off, h,
- &pd, &a, &ruleset);
+ &pd, &a, &ruleset, &ipintrq);
break;
}
@@ -5662,7 +5678,7 @@ pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0)
log = s->log;
} else if (s == NULL)
action = pf_test_tcp(&r, &s, dir, kif,
- m, off, h, &pd, &a, &ruleset);
+ m, off, h, &pd, &a, &ruleset, &ip6intrq);
break;
}
@@ -5696,7 +5712,7 @@ pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0)
log = s->log;
} else if (s == NULL)
action = pf_test_udp(&r, &s, dir, kif,
- m, off, h, &pd, &a, &ruleset);
+ m, off, h, &pd, &a, &ruleset, &ip6intrq);
break;
}
@@ -5725,7 +5741,7 @@ pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0)
log = s->log;
} else if (s == NULL)
action = pf_test_icmp(&r, &s, dir, kif,
- m, off, h, &pd, &a, &ruleset);
+ m, off, h, &pd, &a, &ruleset, &ip6intrq);
break;
}
@@ -5737,7 +5753,7 @@ pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0)
log = s->log;
} else if (s == NULL)
action = pf_test_other(&r, &s, dir, kif, m, off, h,
- &pd, &a, &ruleset);
+ &pd, &a, &ruleset, &ip6intrq);
break;
}
@@ -5852,3 +5868,12 @@ done:
return (action);
}
#endif /* INET6 */
+
+int
+pf_check_congestion(struct ifqueue *ifq)
+{
+ if (ifq->ifq_congestion)
+ return (1);
+ else
+ return (0);
+}