diff --git a/src/kern/npf.h b/src/kern/npf.h index 1c47c6a4..96856d7a 100644 --- a/src/kern/npf.h +++ b/src/kern/npf.h @@ -362,4 +362,45 @@ typedef enum { #define NPF_STATS_SIZE (sizeof(uint64_t) * NPF_STATS_COUNT) +/* + * Generic connection states and timeout table. + * + * Note: used for connection-less protocols. + */ + +#define NPF_ANY_CONN_CLOSED 0 +#define NPF_ANY_CONN_NEW 1 +#define NPF_ANY_CONN_ESTABLISHED 2 + +#define NPF_ANY_CONN_NSTATES 3 + + +/* + * NPF TCP states. Note: these states are different from the TCP FSM + * states of RFC 793. The packet filter is a man-in-the-middle. + */ +#define NPF_TCPS_OK 255 +#define NPF_TCPS_CLOSED 0 +#define NPF_TCPS_SYN_SENT 1 +#define NPF_TCPS_SIMSYN_SENT 2 +#define NPF_TCPS_SYN_RECEIVED 3 +#define NPF_TCPS_ESTABLISHED 4 +#define NPF_TCPS_FIN_SENT 5 +#define NPF_TCPS_FIN_RECEIVED 6 +#define NPF_TCPS_CLOSE_WAIT 7 +#define NPF_TCPS_FIN_WAIT 8 +#define NPF_TCPS_CLOSING 9 +#define NPF_TCPS_LAST_ACK 10 +#define NPF_TCPS_TIME_WAIT 11 + +#define NPF_TCP_NSTATES 12 + +/* + * Connection db summary + */ +/* TCP states + any states + GRE state */ +#define NPF_CONNDB_SUMM_NSTATES (NPF_TCP_NSTATES + NPF_ANY_CONN_NSTATES + 1) +#define NPF_CONNDB_SUMM_ANY_STATE_OFFS NPF_TCP_NSTATES +#define NPF_CONNDB_SUMM_GRE_STATE (NPF_TCP_NSTATES + NPF_ANY_CONN_NSTATES) + #endif /* _NPF_NET_H_ */ diff --git a/src/kern/npf_conndb.c b/src/kern/npf_conndb.c index 9827ace3..0b3ffc1c 100644 --- a/src/kern/npf_conndb.c +++ b/src/kern/npf_conndb.c @@ -60,6 +60,8 @@ __KERNEL_RCSID(0, "$NetBSD: npf_conndb.c,v 1.5 2019/01/19 21:19:31 rmind Exp $") #include "npf_conn.h" #include "npf_impl.h" +#define NPF_CONNDB_SUMM_NUM_COPIES 2 + struct npf_conndb { thmap_t * cd_map; @@ -76,6 +78,10 @@ struct npf_conndb { /* The last inspected connection (for circular iteration). */ npf_conn_t * cd_marker; + + /* connection db summary stat */ + uint8_t summary_work_copy_ind; /* current working summary copy */ + uint32_t summary[NPF_CONNDB_SUMM_NUM_COPIES][NPF_CONNDB_SUMM_NSTATES]; }; typedef struct { @@ -273,6 +279,48 @@ npf_conndb_getnext(npf_conndb_t *cd, npf_conn_t *con) return con; } +/* + * Clear conndb summary stat working copy + */ +static void +npf_conndb_summary_clear(npf_conndb_t *cd) +{ + uint8_t ind; + + ind = cd->summary_work_copy_ind & (NPF_CONNDB_SUMM_NUM_COPIES - 1); + memset(&cd->summary[ind], 0, sizeof(cd->summary[0][0]) * + NPF_CONNDB_SUMM_NSTATES); +} + +/* + */ +static void +npf_conndb_summary_inc(npf_conndb_t *cd, npf_conn_t *con) +{ + unsigned state; + uint8_t ind; + + ind = cd->summary_work_copy_ind & (NPF_CONNDB_SUMM_NUM_COPIES - 1); + + switch (con->c_proto) { + case IPPROTO_TCP: + state = con->c_state.nst_state; + break; + + case IPPROTO_GRE: + state = NPF_CONNDB_SUMM_GRE_STATE; + break; + + default: + if (con->c_state.nst_state >= NPF_ANY_CONN_NSTATES) + return; + state = NPF_CONNDB_SUMM_ANY_STATE_OFFS + con->c_state.nst_state; + break; + } + + cd->summary[ind][state]++; +} + /* * npf_conndb_gc_incr: incremental G/C of the expired connections. */ @@ -301,6 +349,13 @@ npf_conndb_gc_incr(npf_t *npf, npf_conndb_t *cd, const time_t now) while (con && target--) { npf_conn_t *next = npf_conndb_getnext(cd, con); + /* keep track of conndb statistic */ + if (con == LIST_FIRST(&cd->cd_list)) { + /* start new summary cycle */ + cd->summary_work_copy_ind++; + npf_conndb_summary_clear(cd); + } + /* * Can we G/C this connection? */ @@ -322,6 +377,9 @@ npf_conndb_gc_incr(npf_t *npf, npf_conndb_t *cd, const time_t now) } con = next; + /* keep track of conndb statistic */ + npf_conndb_summary_inc(cd, con); + /* * Circular iteration: if we returned back to the * marker connection, then stop. @@ -407,3 +465,16 @@ npf_conndb_gc(npf_t *npf, npf_conndb_t *cd, bool flush, bool sync) npf_conn_destroy(npf, con); } } + +/* + * Return reference to the conndb summary array + */ +__dso_public uint32_t * +npf_conndb_summary(const npf_t *npf) +{ + uint8_t ind; + + ind = (npf->conn_db->summary_work_copy_ind + 1) & + (NPF_CONNDB_SUMM_NUM_COPIES - 1); + return &npf->conn_db->summary[ind][0]; +} diff --git a/src/kern/npf_state.c b/src/kern/npf_state.c index be06a5fe..2f8e4229 100644 --- a/src/kern/npf_state.c +++ b/src/kern/npf_state.c @@ -42,17 +42,6 @@ __KERNEL_RCSID(0, "$NetBSD: npf_state.c,v 1.21 2018/10/29 15:37:06 christos Exp #include "npf_impl.h" -/* - * Generic connection states and timeout table. - * - * Note: used for connection-less protocols. - */ - -#define NPF_ANY_CONN_CLOSED 0 -#define NPF_ANY_CONN_NEW 1 -#define NPF_ANY_CONN_ESTABLISHED 2 -#define NPF_ANY_CONN_NSTATES 3 - /* * Parameters. */ diff --git a/src/kern/npf_state_tcp.c b/src/kern/npf_state_tcp.c index 71074193..edbeb4fe 100644 --- a/src/kern/npf_state_tcp.c +++ b/src/kern/npf_state_tcp.c @@ -44,26 +44,6 @@ __KERNEL_RCSID(0, "$NetBSD: npf_state_tcp.c,v 1.19 2018/09/29 14:41:36 rmind Exp #include "npf_impl.h" -/* - * NPF TCP states. Note: these states are different from the TCP FSM - * states of RFC 793. The packet filter is a man-in-the-middle. - */ -#define NPF_TCPS_OK 255 -#define NPF_TCPS_CLOSED 0 -#define NPF_TCPS_SYN_SENT 1 -#define NPF_TCPS_SIMSYN_SENT 2 -#define NPF_TCPS_SYN_RECEIVED 3 -#define NPF_TCPS_ESTABLISHED 4 -#define NPF_TCPS_FIN_SENT 5 -#define NPF_TCPS_FIN_RECEIVED 6 -#define NPF_TCPS_CLOSE_WAIT 7 -#define NPF_TCPS_FIN_WAIT 8 -#define NPF_TCPS_CLOSING 9 -#define NPF_TCPS_LAST_ACK 10 -#define NPF_TCPS_TIME_WAIT 11 - -#define NPF_TCP_NSTATES 12 - /* Timeouts */ #define NPF_TCPT_NEW 0 #define NPF_TCPT_ESTABLISHED 1 diff --git a/src/kern/npfkern.h b/src/kern/npfkern.h index 7d69b589..c7eb401f 100644 --- a/src/kern/npfkern.h +++ b/src/kern/npfkern.h @@ -86,4 +86,7 @@ void npf_stats_clear(npf_t *); int npf_alg_icmp_init(npf_t *); int npf_alg_icmp_fini(npf_t *); +/* conndb summary */ +uint32_t * npf_conndb_summary(const npf_t *npf); + #endif