Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dist/pf/net Resolve conflicts (pf from OpenBSD 3.7, kern...
details: https://anonhg.NetBSD.org/src/rev/47ae8d4569fe
branches: trunk
changeset: 582585:47ae8d4569fe
user: peter <peter%NetBSD.org@localhost>
date: Fri Jul 01 12:37:34 2005 +0000
description:
Resolve conflicts (pf from OpenBSD 3.7, kernel part).
diffstat:
sys/dist/pf/net/pf.c | 598 +++++++++++++++++++++++++++++++++++---------
sys/dist/pf/net/pf_if.c | 53 +++-
sys/dist/pf/net/pf_ioctl.c | 165 ++++++++++--
sys/dist/pf/net/pf_norm.c | 10 +-
sys/dist/pf/net/pf_table.c | 90 ++++++-
sys/dist/pf/net/pfvar.h | 114 ++++++++-
6 files changed, 855 insertions(+), 175 deletions(-)
diffs (truncated from 2245 to 300 lines):
diff -r 33a5a055cc7f -r 47ae8d4569fe sys/dist/pf/net/pf.c
--- a/sys/dist/pf/net/pf.c Fri Jul 01 12:35:18 2005 +0000
+++ b/sys/dist/pf/net/pf.c Fri Jul 01 12:37:34 2005 +0000
@@ -1,5 +1,5 @@
-/* $NetBSD: pf.c,v 1.16 2005/06/15 01:48:20 lukem Exp $ */
-/* $OpenBSD: pf.c,v 1.457.2.7 2005/01/06 14:11:56 brad Exp $ */
+/* $NetBSD: pf.c,v 1.17 2005/07/01 12:37:34 peter Exp $ */
+/* $OpenBSD: pf.c,v 1.483 2005/03/15 17:38:43 dhartmei Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -141,6 +141,11 @@
void pf_print_host(struct pf_addr *, u_int16_t, u_int8_t);
+void pf_init_threshold(struct pf_threshold *, u_int32_t,
+ u_int32_t);
+void pf_add_threshold(struct pf_threshold *);
+int pf_check_threshold(struct pf_threshold *);
+
void pf_change_ap(struct pf_addr *, u_int16_t *,
u_int16_t *, u_int16_t *, struct pf_addr *,
u_int16_t, u_int8_t, sa_family_t);
@@ -196,12 +201,12 @@
void *, struct pf_pdesc *);
int pf_test_state_icmp(struct pf_state **, int,
struct pfi_kif *, struct mbuf *, int,
- void *, struct pf_pdesc *);
+ void *, struct pf_pdesc *, u_short *);
int pf_test_state_other(struct pf_state **, int,
struct pfi_kif *, struct pf_pdesc *);
struct pf_tag *pf_get_tag(struct mbuf *);
int pf_match_tag(struct mbuf *, struct pf_rule *,
- struct pf_rule *, struct pf_tag **, int *);
+ struct pf_tag **, int *);
void pf_hash(struct pf_addr *, struct pf_addr *,
struct pf_poolhashkey *, sa_family_t);
int pf_map_addr(u_int8_t, struct pf_rule *,
@@ -232,6 +237,7 @@
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_src_connlimit(struct pf_state **);
int pf_check_congestion(struct ifqueue *);
struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX] = {
@@ -243,12 +249,12 @@
#define STATE_LOOKUP() \
do { \
if (direction == PF_IN) \
- *state = pf_find_state_recurse( \
+ *state = pf_find_state_recurse( \
kif, &key, PF_EXT_GWY); \
else \
- *state = pf_find_state_recurse( \
+ *state = pf_find_state_recurse( \
kif, &key, PF_LAN_EXT); \
- if (*state == NULL) \
+ if (*state == NULL || (*state)->timeout == PFTM_PURGE) \
return (PF_DROP); \
if (direction == PF_OUT && \
(((*state)->rule.ptr->rt == PF_ROUTETO && \
@@ -272,6 +278,24 @@
((r)->rule_flag & PFRULE_GRBOUND) ? (k)->pfik_parent : \
(k)->pfik_parent->pfik_parent)
+#define STATE_INC_COUNTERS(s) \
+ do { \
+ s->rule.ptr->states++; \
+ if (s->anchor.ptr != NULL) \
+ s->anchor.ptr->states++; \
+ if (s->nat_rule.ptr != NULL) \
+ s->nat_rule.ptr->states++; \
+ } while (0)
+
+#define STATE_DEC_COUNTERS(s) \
+ do { \
+ if (s->nat_rule.ptr != NULL) \
+ s->nat_rule.ptr->states--; \
+ if (s->anchor.ptr != NULL) \
+ s->anchor.ptr->states--; \
+ s->rule.ptr->states--; \
+ } while (0)
+
static __inline int pf_src_compare(struct pf_src_node *, struct pf_src_node *);
static __inline int pf_state_compare_lan_ext(struct pf_state *,
struct pf_state *);
@@ -593,6 +617,131 @@
}
}
+void
+pf_init_threshold(struct pf_threshold *threshold,
+ u_int32_t limit, u_int32_t seconds)
+{
+ threshold->limit = limit * PF_THRESHOLD_MULT;
+ threshold->seconds = seconds;
+ threshold->count = 0;
+ threshold->last = time_second;
+}
+
+void
+pf_add_threshold(struct pf_threshold *threshold)
+{
+ u_int32_t t = time_second, diff = t - threshold->last;
+
+ if (diff >= threshold->seconds)
+ threshold->count = 0;
+ else
+ threshold->count -= threshold->count * diff /
+ threshold->seconds;
+ threshold->count += PF_THRESHOLD_MULT;
+ threshold->last = t;
+}
+
+int
+pf_check_threshold(struct pf_threshold *threshold)
+{
+ return (threshold->count > threshold->limit);
+}
+
+int
+pf_src_connlimit(struct pf_state **state)
+{
+ struct pf_state *s;
+ int bad = 0;
+
+ (*state)->src_node->conn++;
+ pf_add_threshold(&(*state)->src_node->conn_rate);
+
+ if ((*state)->rule.ptr->max_src_conn &&
+ (*state)->rule.ptr->max_src_conn <
+ (*state)->src_node->conn) {
+ pf_status.lcounters[LCNT_SRCCONN]++;
+ bad++;
+ }
+
+ if ((*state)->rule.ptr->max_src_conn_rate.limit &&
+ pf_check_threshold(&(*state)->src_node->conn_rate)) {
+ pf_status.lcounters[LCNT_SRCCONNRATE]++;
+ bad++;
+ }
+
+ if (!bad)
+ return (0);
+
+ if ((*state)->rule.ptr->overload_tbl) {
+ struct pfr_addr p;
+ u_int32_t killed = 0;
+
+ pf_status.lcounters[LCNT_OVERLOAD_TABLE]++;
+ if (pf_status.debug >= PF_DEBUG_MISC) {
+ printf("pf_src_connlimit: blocking address ");
+ pf_print_host(&(*state)->src_node->addr, 0,
+ (*state)->af);
+ }
+
+ bzero(&p, sizeof(p));
+ p.pfra_af = (*state)->af;
+ switch ((*state)->af) {
+#ifdef INET
+ case AF_INET:
+ p.pfra_net = 32;
+ p.pfra_ip4addr = (*state)->src_node->addr.v4;
+ break;
+#endif /* INET */
+#ifdef INET6
+ case AF_INET6:
+ p.pfra_net = 128;
+ p.pfra_ip6addr = (*state)->src_node->addr.v6;
+ break;
+#endif /* INET6 */
+ }
+
+ pfr_insert_kentry((*state)->rule.ptr->overload_tbl,
+ &p, time_second);
+
+ /* kill existing states if that's required. */
+ if ((*state)->rule.ptr->flush) {
+ pf_status.lcounters[LCNT_OVERLOAD_FLUSH]++;
+
+ RB_FOREACH(s, pf_state_tree_id, &tree_id) {
+ /*
+ * Kill states from this source. (Only those
+ * from the same rule if PF_FLUSH_GLOBAL is not
+ * set)
+ */
+ if (s->af == (*state)->af &&
+ (((*state)->direction == PF_OUT &&
+ PF_AEQ(&(*state)->src_node->addr,
+ &s->lan.addr, s->af)) ||
+ ((*state)->direction == PF_IN &&
+ PF_AEQ(&(*state)->src_node->addr,
+ &s->ext.addr, s->af))) &&
+ ((*state)->rule.ptr->flush &
+ PF_FLUSH_GLOBAL ||
+ (*state)->rule.ptr == s->rule.ptr)) {
+ s->timeout = PFTM_PURGE;
+ s->src.state = s->dst.state =
+ TCPS_CLOSED;
+ killed++;
+ }
+ }
+ if (pf_status.debug >= PF_DEBUG_MISC)
+ printf(", %u states killed", killed);
+ }
+ if (pf_status.debug >= PF_DEBUG_MISC)
+ printf("\n");
+ }
+
+ /* kill this state */
+ (*state)->timeout = PFTM_PURGE;
+ (*state)->src.state = (*state)->dst.state = TCPS_CLOSED;
+ return (1);
+}
+
int
pf_insert_src_node(struct pf_src_node **sn, struct pf_rule *rule,
struct pf_addr *src, sa_family_t af)
@@ -614,9 +763,16 @@
if (!rule->max_src_nodes ||
rule->src_nodes < rule->max_src_nodes)
(*sn) = pool_get(&pf_src_tree_pl, PR_NOWAIT);
+ else
+ pf_status.lcounters[LCNT_SRCNODES]++;
if ((*sn) == NULL)
return (-1);
bzero(*sn, sizeof(struct pf_src_node));
+
+ pf_init_threshold(&(*sn)->conn_rate,
+ rule->max_src_conn_rate.limit,
+ rule->max_src_conn_rate.seconds);
+
(*sn)->af = af;
if (rule->rule_flag & PFRULE_RULESRCTRACK ||
rule->rpool.opts & PF_POOL_STICKYADDR)
@@ -642,8 +798,10 @@
pf_status.src_nodes++;
} else {
if (rule->max_src_states &&
- (*sn)->states >= rule->max_src_states)
+ (*sn)->states >= rule->max_src_states) {
+ pf_status.lcounters[LCNT_SRCSTATES]++;
return (-1);
+ }
}
return (0);
}
@@ -814,6 +972,11 @@
u_int32_t timeout;
if (s->src_node != NULL) {
+ if (s->proto == IPPROTO_TCP) {
+ if (s->src.state == PF_TCPS_PROXY_DST ||
+ s->timeout >= PFTM_TCP_ESTABLISHED)
+ --s->src_node->conn;
+ }
if (--s->src_node->states <= 0) {
timeout = s->rule.ptr->timeout[PFTM_SRC_NODE];
if (!timeout)
@@ -865,6 +1028,8 @@
pf_normalize_tcp_cleanup(cur);
pfi_detach_state(cur->u.s.kif);
TAILQ_REMOVE(&state_updates, cur, u.s.entry_updates);
+ if (cur->tag)
+ pf_tag_unref(cur->tag);
pool_put(&pf_state_pl, cur);
pf_status.fcounters[FCNT_STATE_REMOVALS]++;
pf_status.states--;
@@ -936,7 +1101,7 @@
case AF_INET6: {
u_int16_t b;
u_int8_t i, curstart = 255, curend = 0,
- maxstart = 0, maxend = 0;
+ maxstart = 255, maxend = 255;
for (i = 0; i < 8; i++) {
if (!addr->addr16[i]) {
if (curstart == 255)
@@ -944,19 +1109,22 @@
else
curend = i;
} else {
- if (curstart) {
+ if (curstart != 255) {
if ((curend - curstart) >
(maxend - maxstart)) {
maxstart = curstart;
maxend = curend;
- curstart = 255;
}
+ curstart = 255;
}
}
}
for (i = 0; i < 8; i++) {
if (i >= maxstart && i <= maxend) {
- if (maxend != 7) {
+ if (maxstart == 0) {
+ if (i < 2)
+ printf(":");
Home |
Main Index |
Thread Index |
Old Index