Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 14 Aug 2014 18:57:46 +0000 (UTC)
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r269998 - in head/sys: net netpfil/pf
Message-ID:  <201408141857.s7EIvkGt047351@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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) {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201408141857.s7EIvkGt047351>