Author: glebius
Date: Thu Aug 14 18:57:46 2014
New Revision: 269998
URL: http://svnweb.freebsd.org/changeset/base/269998

Log:
  - Count global pf(4) statistics in counter(9).
  - Do not count global number of states and of src_nodes,
    use uma_zone_get_cur() to obtain values.
  - Struct pf_status becomes merely an ioctl API structure,
    and moves to netpfil/pf/pf.h with its constants.
  - V_pf_status is now of type struct pf_kstatus.
  
  Submitted by: Kajetan Staszkiewicz <vegeta tuxpowered.net>
  Sponsored by: InnoGames GmbH

Modified:
  head/sys/net/pfvar.h
  head/sys/netpfil/pf/pf.c
  head/sys/netpfil/pf/pf.h
  head/sys/netpfil/pf/pf_ioctl.c

Modified: head/sys/net/pfvar.h
==============================================================================
--- head/sys/net/pfvar.h        Thu Aug 14 18:46:36 2014        (r269997)
+++ head/sys/net/pfvar.h        Thu Aug 14 18:57:46 2014        (r269998)
@@ -1123,27 +1123,6 @@ struct pf_pdesc {
 #define PF_DPORT_RANGE 0x01            /* Dest port uses range */
 #define PF_RPORT_RANGE 0x02            /* RDR'ed port uses range */
 
-/* Counters for other things we want to keep track of */
-#define LCNT_STATES            0       /* states */
-#define LCNT_SRCSTATES         1       /* max-src-states */
-#define LCNT_SRCNODES          2       /* max-src-nodes */
-#define LCNT_SRCCONN           3       /* max-src-conn */
-#define LCNT_SRCCONNRATE       4       /* max-src-conn-rate */
-#define LCNT_OVERLOAD_TABLE    5       /* entry added to overload table */
-#define LCNT_OVERLOAD_FLUSH    6       /* state entries flushed */
-#define LCNT_MAX               7       /* total+1 */
-
-#define LCNT_NAMES { \
-       "max states per rule", \
-       "max-src-states", \
-       "max-src-nodes", \
-       "max-src-conn", \
-       "max-src-conn-rate", \
-       "overload table insertion", \
-       "overload flush states", \
-       NULL \
-}
-
 /* UDP state enumeration */
 #define PFUDPS_NO_TRAFFIC      0
 #define PFUDPS_SINGLE          1
@@ -1172,16 +1151,6 @@ struct pf_pdesc {
        NULL \
 }
 
-#define FCNT_STATE_SEARCH      0
-#define FCNT_STATE_INSERT      1
-#define FCNT_STATE_REMOVALS    2
-#define FCNT_MAX               3
-
-#define SCNT_SRC_NODE_SEARCH   0
-#define SCNT_SRC_NODE_INSERT   1
-#define SCNT_SRC_NODE_REMOVALS 2
-#define SCNT_MAX               3
-
 #define ACTION_SET(a, x) \
        do { \
                if ((a) != NULL) \
@@ -1193,24 +1162,22 @@ struct pf_pdesc {
                if ((a) != NULL) \
                        *(a) = (x); \
                if (x < PFRES_MAX) \
-                       V_pf_status.counters[x]++; \
+                       counter_u64_add(V_pf_status.counters[x], 1); \
        } while (0)
 
-struct pf_status {
-       u_int64_t       counters[PFRES_MAX];
-       u_int64_t       lcounters[LCNT_MAX];    /* limit counters */
-       u_int64_t       fcounters[FCNT_MAX];
-       u_int64_t       scounters[SCNT_MAX];
-       u_int64_t       pcounters[2][2][3];
-       u_int64_t       bcounters[2][2];
-       u_int32_t       running;
-       u_int32_t       states;
-       u_int32_t       src_nodes;
-       u_int32_t       since;
-       u_int32_t       debug;
-       u_int32_t       hostid;
+struct pf_kstatus {
+       counter_u64_t   counters[PFRES_MAX]; /* reason for passing/dropping */
+       counter_u64_t   lcounters[LCNT_MAX]; /* limit counters */
+       counter_u64_t   fcounters[FCNT_MAX]; /* state operation counters */
+       counter_u64_t   scounters[SCNT_MAX]; /* src_node operation counters */
+       uint32_t        states;
+       uint32_t        src_nodes;
+       uint32_t        running;
+       uint32_t        since;
+       uint32_t        debug;
+       uint32_t        hostid;
        char            ifname[IFNAMSIZ];
-       u_int8_t        pf_chksum[PF_MD5_DIGEST_LENGTH];
+       uint8_t         pf_chksum[PF_MD5_DIGEST_LENGTH];
 };
 
 struct pf_divert {
@@ -1704,8 +1671,8 @@ int                pf_match_tag(struct mbuf *, struct
 int             pf_tag_packet(struct mbuf *, struct pf_pdesc *, int);
 void            pf_qid2qname(u_int32_t, char *);
 
-VNET_DECLARE(struct pf_status,          pf_status);
-#define        V_pf_status                      VNET(pf_status)
+VNET_DECLARE(struct pf_kstatus, pf_status);
+#define        V_pf_status     VNET(pf_status)
 
 struct pf_limit {
        uma_zone_t      zone;

Modified: head/sys/netpfil/pf/pf.c
==============================================================================
--- head/sys/netpfil/pf/pf.c    Thu Aug 14 18:46:36 2014        (r269997)
+++ head/sys/netpfil/pf/pf.c    Thu Aug 14 18:57:46 2014        (r269998)
@@ -110,7 +110,7 @@ VNET_DEFINE(struct pf_altqqueue,     pf_alt
 VNET_DEFINE(struct pf_palist,           pf_pabuf);
 VNET_DEFINE(struct pf_altqqueue *,      pf_altqs_active);
 VNET_DEFINE(struct pf_altqqueue *,      pf_altqs_inactive);
-VNET_DEFINE(struct pf_status,           pf_status);
+VNET_DEFINE(struct pf_kstatus,          pf_status);
 
 VNET_DEFINE(u_int32_t,                  ticket_altqs_active);
 VNET_DEFINE(u_int32_t,                  ticket_altqs_inactive);
@@ -469,13 +469,13 @@ pf_src_connlimit(struct pf_state **state
        if ((*state)->rule.ptr->max_src_conn &&
            (*state)->rule.ptr->max_src_conn <
            (*state)->src_node->conn) {
-               V_pf_status.lcounters[LCNT_SRCCONN]++;
+               counter_u64_add(V_pf_status.lcounters[LCNT_SRCCONN], 1);
                bad++;
        }
 
        if ((*state)->rule.ptr->max_src_conn_rate.limit &&
            pf_check_threshold(&(*state)->src_node->conn_rate)) {
-               V_pf_status.lcounters[LCNT_SRCCONNRATE]++;
+               counter_u64_add(V_pf_status.lcounters[LCNT_SRCCONNRATE], 1);
                bad++;
        }
 
@@ -523,7 +523,7 @@ pf_overload_task(void *v, int pending)
 
        bzero(&p, sizeof(p));
        SLIST_FOREACH(pfoe, &queue, next) {
-               V_pf_status.lcounters[LCNT_OVERLOAD_TABLE]++;
+               counter_u64_add(V_pf_status.lcounters[LCNT_OVERLOAD_TABLE], 1);
                if (V_pf_status.debug >= PF_DEBUG_MISC) {
                        printf("%s: blocking address ", __func__);
                        pf_print_host(&pfoe->addr, 0, pfoe->af);
@@ -559,7 +559,8 @@ pf_overload_task(void *v, int pending)
                        SLIST_REMOVE(&queue, pfoe, pf_overload_entry, next);
                        free(pfoe, M_PFTEMP);
                } else
-                       V_pf_status.lcounters[LCNT_OVERLOAD_FLUSH]++;
+                       counter_u64_add(
+                           V_pf_status.lcounters[LCNT_OVERLOAD_FLUSH], 1);
 
        /* If nothing to flush, return. */
        if (SLIST_EMPTY(&queue)) {
@@ -609,7 +610,7 @@ pf_find_src_node(struct pf_addr *src, st
        struct pf_srchash *sh;
        struct pf_src_node *n;
 
-       V_pf_status.scounters[SCNT_SRC_NODE_SEARCH]++;
+       counter_u64_add(V_pf_status.scounters[SCNT_SRC_NODE_SEARCH], 1);
 
        sh = &V_pf_srchash[pf_hashsrc(src, af)];
        PF_HASHROW_LOCK(sh);
@@ -645,7 +646,8 @@ pf_insert_src_node(struct pf_src_node **
                    counter_u64_fetch(rule->src_nodes) < rule->max_src_nodes)
                        (*sn) = uma_zalloc(V_pf_sources_z, M_NOWAIT | M_ZERO);
                else
-                       V_pf_status.lcounters[LCNT_SRCNODES]++;
+                       counter_u64_add(V_pf_status.lcounters[LCNT_SRCNODES],
+                           1);
                if ((*sn) == NULL) {
                        PF_HASHROW_UNLOCK(sh);
                        return (-1);
@@ -664,12 +666,12 @@ pf_insert_src_node(struct pf_src_node **
                if ((*sn)->rule.ptr != NULL)
                        counter_u64_add((*sn)->rule.ptr->src_nodes, 1);
                PF_HASHROW_UNLOCK(sh);
-               V_pf_status.scounters[SCNT_SRC_NODE_INSERT]++;
-               V_pf_status.src_nodes++;
+               counter_u64_add(V_pf_status.scounters[SCNT_SRC_NODE_INSERT], 1);
        } else {
                if (rule->max_src_states &&
                    (*sn)->states >= rule->max_src_states) {
-                       V_pf_status.lcounters[LCNT_SRCSTATES]++;
+                       counter_u64_add(V_pf_status.lcounters[LCNT_SRCSTATES],
+                           1);
                        return (-1);
                }
        }
@@ -688,8 +690,7 @@ pf_unlink_src_node_locked(struct pf_src_
        LIST_REMOVE(src, entry);
        if (src->rule.ptr)
                counter_u64_add(src->rule.ptr->src_nodes, -1);
-       V_pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
-       V_pf_status.src_nodes--;
+       counter_u64_add(V_pf_status.scounters[SCNT_SRC_NODE_REMOVALS], 1);
 }
 
 void
@@ -1203,7 +1204,7 @@ pf_state_insert(struct pfi_kif *kif, str
        /* One for keys, one for ID hash. */
        refcount_init(&s->refs, 2);
 
-       V_pf_status.fcounters[FCNT_STATE_INSERT]++;
+       counter_u64_add(V_pf_status.fcounters[FCNT_STATE_INSERT], 1);
        if (pfsync_insert_state_ptr != NULL)
                pfsync_insert_state_ptr(s);
 
@@ -1220,7 +1221,7 @@ pf_find_state_byid(uint64_t id, uint32_t
        struct pf_idhash *ih;
        struct pf_state *s;
 
-       V_pf_status.fcounters[FCNT_STATE_SEARCH]++;
+       counter_u64_add(V_pf_status.fcounters[FCNT_STATE_SEARCH], 1);
 
        ih = &V_pf_idhash[(be64toh(id) % (pf_hashmask + 1))];
 
@@ -1247,7 +1248,7 @@ pf_find_state(struct pfi_kif *kif, struc
        struct pf_state         *s;
        int idx;
 
-       V_pf_status.fcounters[FCNT_STATE_SEARCH]++;
+       counter_u64_add(V_pf_status.fcounters[FCNT_STATE_SEARCH], 1);
 
        kh = &V_pf_keyhash[pf_hashkey((struct pf_state_key *)key)];
 
@@ -1291,7 +1292,7 @@ pf_find_state_all(struct pf_state_key_cm
        struct pf_state         *s, *ret = NULL;
        int                      idx, inout = 0;
 
-       V_pf_status.fcounters[FCNT_STATE_SEARCH]++;
+       counter_u64_add(V_pf_status.fcounters[FCNT_STATE_SEARCH], 1);
 
        kh = &V_pf_keyhash[pf_hashkey((struct pf_state_key *)key)];
 
@@ -1519,6 +1520,8 @@ pf_purge_expired_src_nodes()
        }
 
        pf_free_src_nodes(&freelist);
+
+       V_pf_status.src_nodes = uma_zone_get_cur(V_pf_sources_z);
 }
 
 static void
@@ -1613,7 +1616,7 @@ pf_free_state(struct pf_state *cur)
 
        pf_normalize_tcp_cleanup(cur);
        uma_zfree(V_pf_state_z, cur);
-       V_pf_status.fcounters[FCNT_STATE_REMOVALS]++;
+       counter_u64_add(V_pf_status.fcounters[FCNT_STATE_REMOVALS], 1);
 }
 
 /*
@@ -3454,7 +3457,7 @@ pf_create_state(struct pf_rule *r, struc
        /* check maximums */
        if (r->max_states &&
            (counter_u64_fetch(r->states_cur) >= r->max_states)) {
-               V_pf_status.lcounters[LCNT_STATES]++;
+               counter_u64_add(V_pf_status.lcounters[LCNT_STATES], 1);
                REASON_SET(&reason, PFRES_MAXSTATES);
                return (PF_DROP);
        }

Modified: head/sys/netpfil/pf/pf.h
==============================================================================
--- head/sys/netpfil/pf/pf.h    Thu Aug 14 18:46:36 2014        (r269997)
+++ head/sys/netpfil/pf/pf.h    Thu Aug 14 18:57:46 2014        (r269998)
@@ -145,7 +145,57 @@ enum       { PF_ADDR_ADDRMASK, PF_ADDR_NOROUTE
        NULL \
 }
 
+/* Counters for other things we want to keep track of */
+#define LCNT_STATES            0       /* states */
+#define LCNT_SRCSTATES         1       /* max-src-states */
+#define LCNT_SRCNODES          2       /* max-src-nodes */
+#define LCNT_SRCCONN           3       /* max-src-conn */
+#define LCNT_SRCCONNRATE       4       /* max-src-conn-rate */
+#define LCNT_OVERLOAD_TABLE    5       /* entry added to overload table */
+#define LCNT_OVERLOAD_FLUSH    6       /* state entries flushed */
+#define LCNT_MAX               7       /* total+1 */
+
+#define LCNT_NAMES { \
+       "max states per rule", \
+       "max-src-states", \
+       "max-src-nodes", \
+       "max-src-conn", \
+       "max-src-conn-rate", \
+       "overload table insertion", \
+       "overload flush states", \
+       NULL \
+}
+
+/* state operation counters */
+#define FCNT_STATE_SEARCH      0
+#define FCNT_STATE_INSERT      1
+#define FCNT_STATE_REMOVALS    2
+#define FCNT_MAX               3
+
+/* src_node operation counters */
+#define SCNT_SRC_NODE_SEARCH   0
+#define SCNT_SRC_NODE_INSERT   1
+#define SCNT_SRC_NODE_REMOVALS 2
+#define SCNT_MAX               3
+
 #define        PF_TABLE_NAME_SIZE      32
 #define        PF_QNAME_SIZE           64
 
+struct pf_status {
+       uint64_t        counters[PFRES_MAX];
+       uint64_t        lcounters[LCNT_MAX];
+       uint64_t        fcounters[FCNT_MAX];
+       uint64_t        scounters[SCNT_MAX];
+       uint64_t        pcounters[2][2][3];
+       uint64_t        bcounters[2][2];
+       uint32_t        running;
+       uint32_t        states;
+       uint32_t        src_nodes;
+       uint32_t        since;
+       uint32_t        debug;
+       uint32_t        hostid;
+       char            ifname[IFNAMSIZ];
+       uint8_t         pf_chksum[PF_MD5_DIGEST_LENGTH];
+};
+
 #endif /* _NET_PF_H_ */

Modified: head/sys/netpfil/pf/pf_ioctl.c
==============================================================================
--- head/sys/netpfil/pf/pf_ioctl.c      Thu Aug 14 18:46:36 2014        
(r269997)
+++ head/sys/netpfil/pf/pf_ioctl.c      Thu Aug 14 18:57:46 2014        
(r269998)
@@ -265,6 +265,15 @@ pfattach(void)
        /* XXX do our best to avoid a conflict */
        V_pf_status.hostid = arc4random();
 
+       for (int i = 0; i < PFRES_MAX; i++)
+               V_pf_status.counters[i] = counter_u64_alloc(M_WAITOK);
+       for (int i = 0; i < LCNT_MAX; i++)
+               V_pf_status.lcounters[i] = counter_u64_alloc(M_WAITOK);
+       for (int i = 0; i < FCNT_MAX; i++)
+               V_pf_status.fcounters[i] = counter_u64_alloc(M_WAITOK);
+       for (int i = 0; i < SCNT_MAX; i++)
+               V_pf_status.scounters[i] = counter_u64_alloc(M_WAITOK);
+
        if ((error = kproc_create(pf_purge_thread, curvnet, NULL, 0, 0,
            "pf purge")) != 0)
                /* XXXGL: leaked all above. */
@@ -1787,8 +1796,32 @@ DIOCGETSTATES_full:
 
        case DIOCGETSTATUS: {
                struct pf_status *s = (struct pf_status *)addr;
+
                PF_RULES_RLOCK();
-               bcopy(&V_pf_status, s, sizeof(struct pf_status));
+               s->running = V_pf_status.running;
+               s->since   = V_pf_status.since;
+               s->debug   = V_pf_status.debug;
+               s->hostid  = V_pf_status.hostid;
+               s->states  = V_pf_status.states;
+               s->src_nodes = V_pf_status.src_nodes;
+
+               for (int i = 0; i < PFRES_MAX; i++)
+                       s->counters[i] =
+                           counter_u64_fetch(V_pf_status.counters[i]);
+               for (int i = 0; i < LCNT_MAX; i++)
+                       s->lcounters[i] =
+                           counter_u64_fetch(V_pf_status.lcounters[i]);
+               for (int i = 0; i < FCNT_MAX; i++)
+                       s->fcounters[i] =
+                           counter_u64_fetch(V_pf_status.fcounters[i]);
+               for (int i = 0; i < SCNT_MAX; i++)
+                       s->scounters[i] =
+                           counter_u64_fetch(V_pf_status.scounters[i]);
+
+               bcopy(V_pf_status.ifname, s->ifname, IFNAMSIZ);
+               bcopy(V_pf_status.pf_chksum, s->pf_chksum,
+                   PF_MD5_DIGEST_LENGTH);
+
                pfi_update_status(s->ifname, s);
                PF_RULES_RUNLOCK();
                break;
@@ -1809,9 +1842,12 @@ DIOCGETSTATES_full:
 
        case DIOCCLRSTATUS: {
                PF_RULES_WLOCK();
-               bzero(V_pf_status.counters, sizeof(V_pf_status.counters));
-               bzero(V_pf_status.fcounters, sizeof(V_pf_status.fcounters));
-               bzero(V_pf_status.scounters, sizeof(V_pf_status.scounters));
+               for (int i = 0; i < PFRES_MAX; i++)
+                       counter_u64_zero(V_pf_status.counters[i]);
+               for (int i = 0; i < FCNT_MAX; i++)
+                       counter_u64_zero(V_pf_status.fcounters[i]);
+               for (int i = 0; i < SCNT_MAX; i++)
+                       counter_u64_zero(V_pf_status.scounters[i]);
                V_pf_status.since = time_second;
                if (*V_pf_status.ifname)
                        pfi_update_status(V_pf_status.ifname, NULL);
@@ -3157,7 +3193,6 @@ DIOCCHANGEADDR_error:
 
                pf_clear_srcnodes(NULL);
                pf_purge_expired_src_nodes();
-               V_pf_status.src_nodes = 0;
                break;
        }
 
@@ -3455,6 +3490,15 @@ shutdown_pf(void)
        counter_u64_free(V_pf_default_rule.states_tot);
        counter_u64_free(V_pf_default_rule.src_nodes);
 
+       for (int i = 0; i < PFRES_MAX; i++)
+               counter_u64_free(V_pf_status.counters[i]);
+       for (int i = 0; i < LCNT_MAX; i++)
+               counter_u64_free(V_pf_status.lcounters[i]);
+       for (int i = 0; i < FCNT_MAX; i++)
+               counter_u64_free(V_pf_status.fcounters[i]);
+       for (int i = 0; i < SCNT_MAX; i++)
+               counter_u64_free(V_pf_status.scounters[i]);
+
        do {
                if ((error = pf_begin_rules(&t[0], PF_RULESET_SCRUB, &nn))
                    != 0) {
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to