diff options
author | Gleb Smirnoff <glebius@FreeBSD.org> | 2014-08-14 18:57:46 +0000 |
---|---|---|
committer | Gleb Smirnoff <glebius@FreeBSD.org> | 2014-08-14 18:57:46 +0000 |
commit | a9572d8f02519b4cb8df9ed16ea63c10be0e927d (patch) | |
tree | daedb2dbddf301f66439d0836a4a3a90d65ced56 /sys/netpfil/pf | |
parent | 67e3b91b31065a519624f1b3d754de213c471720 (diff) | |
download | src-a9572d8f02519b4cb8df9ed16ea63c10be0e927d.tar.gz src-a9572d8f02519b4cb8df9ed16ea63c10be0e927d.zip |
- 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
Notes
Notes:
svn path=/head/; revision=269998
Diffstat (limited to 'sys/netpfil/pf')
-rw-r--r-- | sys/netpfil/pf/pf.c | 39 | ||||
-rw-r--r-- | sys/netpfil/pf/pf.h | 50 | ||||
-rw-r--r-- | sys/netpfil/pf/pf_ioctl.c | 54 |
3 files changed, 120 insertions, 23 deletions
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 6c971516e560..ec7c786416b9 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -110,7 +110,7 @@ VNET_DEFINE(struct pf_altqqueue, pf_altqs[2]); 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, struct pf_rule *rule, sa_family_t af, 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 **sn, struct pf_rule *rule, 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 **sn, struct pf_rule *rule, 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_node *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, struct pf_state_key *skw, /* 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 creatorid) 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, struct pf_state_key_cmp *key, u_int dir) 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_cmp *key, u_int dir, int *more) 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, struct pf_rule *nr, struct pf_rule *a, /* 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); } diff --git a/sys/netpfil/pf/pf.h b/sys/netpfil/pf/pf.h index d2d9f2ba49c9..91ae0b640007 100644 --- a/sys/netpfil/pf/pf.h +++ b/sys/netpfil/pf/pf.h @@ -145,7 +145,57 @@ enum { PF_ADDR_ADDRMASK, PF_ADDR_NOROUTE, PF_ADDR_DYNIFTL, 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_ */ diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c index 9a5dfcf577ef..195aeb381461 100644 --- a/sys/netpfil/pf/pf_ioctl.c +++ b/sys/netpfil/pf/pf_ioctl.c @@ -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) { |