pf: Add counters for syncookies

Count when we send a syncookie, receive a valid syncookie or detect a
synflood.

Reviewed by:	kbowling
MFC after:	1 week
Sponsored by:	Modirum MDPay
Differential Revision:	https://reviews.freebsd.org/D31713
This commit is contained in:
Kristof Provost 2021-08-29 15:54:50 +02:00
parent 0f49ecffb7
commit 4cab80a8df
4 changed files with 27 additions and 6 deletions

View File

@ -1378,7 +1378,7 @@ enum pf_syncookies_mode {
#ifdef _KERNEL
struct pf_kstatus {
counter_u64_t counters[PFRES_MAX]; /* reason for passing/dropping */
counter_u64_t lcounters[LCNT_MAX]; /* limit counters */
counter_u64_t lcounters[KLCNT_MAX]; /* limit counters */
struct pf_counter_u64 fcounters[FCNT_MAX]; /* state operation counters */
counter_u64_t scounters[SCNT_MAX]; /* src_node operation counters */
uint32_t states;

View File

@ -161,6 +161,11 @@ enum { PF_ADDR_ADDRMASK, PF_ADDR_NOROUTE, PF_ADDR_DYNIFTL,
#define LCNT_OVERLOAD_TABLE 5 /* entry added to overload table */
#define LCNT_OVERLOAD_FLUSH 6 /* state entries flushed */
#define LCNT_MAX 7 /* total+1 */
/* Only available via the nvlist-based API */
#define KLCNT_SYNFLOODS 7 /* synfloods detected */
#define KLCNT_SYNCOOKIES_SENT 8 /* syncookies sent */
#define KLCNT_SYNCOOKIES_VALID 9 /* syncookies validated */
#define KLCNT_MAX 10 /* total+1 */
#define LCNT_NAMES { \
"max states per rule", \
@ -172,6 +177,19 @@ enum { PF_ADDR_ADDRMASK, PF_ADDR_NOROUTE, PF_ADDR_DYNIFTL,
"overload flush states", \
NULL \
}
#define KLCNT_NAMES { \
"max states per rule", \
"max-src-states", \
"max-src-nodes", \
"max-src-conn", \
"max-src-conn-rate", \
"overload table insertion", \
"overload flush states", \
"synfloods detected", \
"syncookies sent", \
"syncookies validated", \
NULL \
}
/* state operation counters */
#define FCNT_STATE_SEARCH 0

View File

@ -368,7 +368,7 @@ pfattach_vnet(void)
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++)
for (int i = 0; i < KLCNT_MAX; i++)
V_pf_status.lcounters[i] = counter_u64_alloc(M_WAITOK);
for (int i = 0; i < FCNT_MAX; i++)
pf_counter_u64_init(&V_pf_status.fcounters[i], M_WAITOK);
@ -3125,7 +3125,7 @@ DIOCGETSTATESV2_full:
pf_counter_u64_zero(&V_pf_status.fcounters[i]);
for (int i = 0; i < SCNT_MAX; i++)
counter_u64_zero(V_pf_status.scounters[i]);
for (int i = 0; i < LCNT_MAX; i++)
for (int i = 0; i < KLCNT_MAX; i++)
counter_u64_zero(V_pf_status.lcounters[i]);
V_pf_status.since = time_second;
if (*V_pf_status.ifname)
@ -4927,7 +4927,7 @@ pf_getstatus(struct pfioc_nv *nv)
int error;
struct pf_status s;
char *pf_reasons[PFRES_MAX+1] = PFRES_NAMES;
char *pf_lcounter[LCNT_MAX+1] = LCNT_NAMES;
char *pf_lcounter[KLCNT_MAX+1] = KLCNT_NAMES;
char *pf_fcounter[FCNT_MAX+1] = FCNT_NAMES;
PF_RULES_RLOCK_TRACKER;
@ -4954,7 +4954,7 @@ pf_getstatus(struct pfioc_nv *nv)
/* lcounters */
error = pf_add_status_counters(nvl, "lcounters", V_pf_status.lcounters,
LCNT_MAX, pf_lcounter);
KLCNT_MAX, pf_lcounter);
if (error != 0)
ERROUT(error);
@ -5805,7 +5805,7 @@ pf_unload_vnet(void)
for (int i = 0; i < PFRES_MAX; i++)
counter_u64_free(V_pf_status.counters[i]);
for (int i = 0; i < LCNT_MAX; i++)
for (int i = 0; i < KLCNT_MAX; i++)
counter_u64_free(V_pf_status.lcounters[i]);
for (int i = 0; i < FCNT_MAX; i++)
pf_counter_u64_deinit(&V_pf_status.fcounters[i]);

View File

@ -256,6 +256,7 @@ pf_syncookie_send(struct mbuf *m, int off, struct pf_pdesc *pd)
pf_send_tcp(NULL, pd->af, pd->dst, pd->src, *pd->dport, *pd->sport,
iss, ntohl(pd->hdr.tcp.th_seq) + 1, TH_SYN|TH_ACK, 0, mss,
0, 1, 0);
counter_u64_add(V_pf_status.lcounters[KLCNT_SYNCOOKIES_SENT], 1);
}
uint8_t
@ -275,6 +276,8 @@ pf_syncookie_validate(struct pf_pdesc *pd)
if ((ack & ~0xff) != (hash & ~0xff))
return (0);
counter_u64_add(V_pf_status.lcounters[KLCNT_SYNCOOKIES_VALID], 1);
return (1);
}