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