pf: Show pf fragment reassembly counters.
Framgent count and statistics are stored in struct pf_status. From there pfctl(8) and systat(1) collect and show them. Note that pfctl -s info needs the -v switch to show fragments. input claudio@; OK henning@ Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, 19e99d0613 Sponsored by: Rubicon Communications, LLC ("Netgate")
This commit is contained in:
@@ -391,6 +391,8 @@ static const struct snl_attr_parser ap_getstatus[] = {
|
||||
{ .type = PF_GS_CHKSUM, .off = _OUT(pf_chksum), .arg_u32 = PF_MD5_DIGEST_LENGTH, .cb = snl_attr_get_bytes },
|
||||
{ .type = PF_GS_BCOUNTERS, .off = _OUT(bcounters), .arg_u32 = 2 * 2, .cb = snl_attr_get_uint64_array },
|
||||
{ .type = PF_GS_PCOUNTERS, .off = _OUT(pcounters), .arg_u32 = 2 * 2 * 2, .cb = snl_attr_get_uint64_array },
|
||||
{ .type = PF_GS_NCOUNTERS, .off = _OUT(ncounters), .cb = snl_attr_get_counters },
|
||||
{ .type = PF_GS_FRAGMENTS, .off = _OUT(fragments), .cb = snl_attr_get_uint64 },
|
||||
};
|
||||
SNL_DECLARE_PARSER(getstatus_parser, struct genlmsghdr, snl_f_p_empty, ap_getstatus);
|
||||
#undef _OUT
|
||||
@@ -429,6 +431,7 @@ pfctl_get_status_h(struct pfctl_handle *h)
|
||||
TAILQ_INIT(&status->lcounters);
|
||||
TAILQ_INIT(&status->fcounters);
|
||||
TAILQ_INIT(&status->scounters);
|
||||
TAILQ_INIT(&status->ncounters);
|
||||
|
||||
while ((hdr = snl_read_reply_multi(&h->ss, seq_id, &e)) != NULL) {
|
||||
if (! snl_parse_nlmsg(&h->ss, hdr, &getstatus_parser, status))
|
||||
|
||||
@@ -62,6 +62,8 @@ struct pfctl_status {
|
||||
struct pfctl_status_counters lcounters;
|
||||
struct pfctl_status_counters fcounters;
|
||||
struct pfctl_status_counters scounters;
|
||||
struct pfctl_status_counters ncounters;
|
||||
uint64_t fragments;
|
||||
uint64_t pcounters[2][2][2];
|
||||
uint64_t bcounters[2][2];
|
||||
};
|
||||
|
||||
@@ -614,6 +614,20 @@ print_status(struct pfctl_status *s, struct pfctl_syncookies *cookies, int opts)
|
||||
printf("%14s\n", "");
|
||||
}
|
||||
}
|
||||
if (opts & PF_OPT_VERBOSE) {
|
||||
printf("Fragments\n");
|
||||
printf(" %-25s %14ju %14s\n", "current entries",
|
||||
s->fragments, "");
|
||||
TAILQ_FOREACH(c, &s->ncounters, entry) {
|
||||
printf(" %-25s %14ju ", c->name,
|
||||
c->counter);
|
||||
if (runtime > 0)
|
||||
printf("%14.1f/s\n",
|
||||
(double)c->counter / (double)runtime);
|
||||
else
|
||||
printf("%14s\n", "");
|
||||
}
|
||||
}
|
||||
printf("Counters\n");
|
||||
TAILQ_FOREACH(c, &s->counters, entry) {
|
||||
printf(" %-25s %14ju ", c->name, c->counter);
|
||||
|
||||
@@ -1751,6 +1751,7 @@ struct pf_kstatus {
|
||||
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 */
|
||||
counter_u64_t ncounters[NCNT_MAX];
|
||||
uint32_t states;
|
||||
uint32_t src_nodes;
|
||||
uint32_t running;
|
||||
@@ -2440,6 +2441,7 @@ int pf_match_port(u_int8_t, u_int16_t, u_int16_t, u_int16_t);
|
||||
|
||||
void pf_normalize_init(void);
|
||||
void pf_normalize_cleanup(void);
|
||||
uint64_t pf_normalize_get_frag_count(void);
|
||||
int pf_normalize_tcp(struct pf_pdesc *);
|
||||
void pf_normalize_tcp_cleanup(struct pf_kstate *);
|
||||
int pf_normalize_tcp_init(struct pf_pdesc *,
|
||||
|
||||
@@ -247,6 +247,12 @@ enum { PF_ADDR_ADDRMASK, PF_ADDR_NOROUTE, PF_ADDR_DYNIFTL,
|
||||
#define SCNT_SRC_NODE_REMOVALS 2
|
||||
#define SCNT_MAX 3
|
||||
|
||||
/* fragment counters */
|
||||
#define NCNT_FRAG_SEARCH 0
|
||||
#define NCNT_FRAG_INSERT 1
|
||||
#define NCNT_FRAG_REMOVALS 2
|
||||
#define NCNT_MAX 3
|
||||
|
||||
#define PF_TABLE_NAME_SIZE 32
|
||||
#define PF_QNAME_SIZE 64
|
||||
|
||||
|
||||
@@ -421,6 +421,8 @@ pfattach_vnet(void)
|
||||
pf_counter_u64_init(&V_pf_status.fcounters[i], M_WAITOK);
|
||||
for (int i = 0; i < SCNT_MAX; i++)
|
||||
V_pf_status.scounters[i] = counter_u64_alloc(M_WAITOK);
|
||||
for (int i = 0; i < NCNT_MAX; i++)
|
||||
V_pf_status.ncounters[i] = counter_u64_alloc(M_WAITOK);
|
||||
|
||||
if (swi_add(&V_pf_swi_ie, "pf send", pf_intr, curvnet, SWI_NET,
|
||||
INTR_MPSAFE, &V_pf_swi_cookie) != 0)
|
||||
@@ -2508,6 +2510,8 @@ pf_ioctl_clear_status(void)
|
||||
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 < NCNT_MAX; i++)
|
||||
counter_u64_zero(V_pf_status.ncounters[i]);
|
||||
for (int i = 0; i < KLCNT_MAX; i++)
|
||||
counter_u64_zero(V_pf_status.lcounters[i]);
|
||||
V_pf_status.since = time_uptime;
|
||||
@@ -6949,6 +6953,8 @@ pf_unload_vnet(void)
|
||||
pf_counter_u64_deinit(&V_pf_status.fcounters[i]);
|
||||
for (int i = 0; i < SCNT_MAX; i++)
|
||||
counter_u64_free(V_pf_status.scounters[i]);
|
||||
for (int i = 0; i < NCNT_MAX; i++)
|
||||
counter_u64_free(V_pf_status.ncounters[i]);
|
||||
|
||||
rm_destroy(&V_pf_rules_lock);
|
||||
sx_destroy(&V_pf_ioctl_lock);
|
||||
|
||||
@@ -1234,6 +1234,9 @@ pf_handle_get_status(struct nlmsghdr *hdr, struct nl_pstate *npt)
|
||||
V_pf_status.fcounters);
|
||||
nlattr_add_counters(nw, PF_GS_SCOUNTERS, SCNT_MAX, pf_fcounter,
|
||||
V_pf_status.scounters);
|
||||
nlattr_add_counters(nw, PF_GS_NCOUNTERS, NCNT_MAX, pf_fcounter,
|
||||
V_pf_status.ncounters);
|
||||
nlattr_add_u64(nw, PF_GS_FRAGMENTS, pf_normalize_get_frag_count());
|
||||
|
||||
pfi_update_status(V_pf_status.ifname, &s);
|
||||
nlattr_add_u64_array(nw, PF_GS_BCOUNTERS, 2 * 2, (uint64_t *)s.bcounters);
|
||||
|
||||
@@ -352,6 +352,8 @@ enum pf_get_status_types_t {
|
||||
PF_GS_CHKSUM = 14, /* byte array */
|
||||
PF_GS_PCOUNTERS = 15, /* u64 array */
|
||||
PF_GS_BCOUNTERS = 16, /* u64 array */
|
||||
PF_GS_NCOUNTERS = 17, /* nested, */
|
||||
PF_GS_FRAGMENTS = 18, /* u64, */
|
||||
};
|
||||
|
||||
enum pf_natlook_types_t {
|
||||
|
||||
@@ -211,6 +211,12 @@ pf_normalize_cleanup(void)
|
||||
mtx_destroy(&V_pf_frag_mtx);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
pf_normalize_get_frag_count(void)
|
||||
{
|
||||
return (uma_zone_get_cur(V_pf_frent_z));
|
||||
}
|
||||
|
||||
static int
|
||||
pf_frnode_compare(struct pf_frnode *a, struct pf_frnode *b)
|
||||
{
|
||||
@@ -314,6 +320,7 @@ pf_free_fragment(struct pf_fragment *frag)
|
||||
/* Free all fragment entries */
|
||||
while ((frent = TAILQ_FIRST(&frag->fr_queue)) != NULL) {
|
||||
TAILQ_REMOVE(&frag->fr_queue, frent, fr_next);
|
||||
counter_u64_add(V_pf_status.ncounters[NCNT_FRAG_REMOVALS], 1);
|
||||
|
||||
m_freem(frent->fe_m);
|
||||
uma_zfree(V_pf_frent_z, frent);
|
||||
@@ -331,6 +338,7 @@ pf_find_fragment(struct pf_frnode *key, uint32_t id)
|
||||
PF_FRAG_ASSERT();
|
||||
|
||||
frnode = RB_FIND(pf_frnode_tree, &V_pf_frnode_tree, key);
|
||||
counter_u64_add(V_pf_status.ncounters[NCNT_FRAG_SEARCH], 1);
|
||||
if (frnode == NULL)
|
||||
return (NULL);
|
||||
MPASS(frnode->fn_fragments >= 1);
|
||||
@@ -438,6 +446,7 @@ pf_frent_insert(struct pf_fragment *frag, struct pf_frent *frent,
|
||||
("overlapping fragment"));
|
||||
TAILQ_INSERT_AFTER(&frag->fr_queue, prev, frent, fr_next);
|
||||
}
|
||||
counter_u64_add(V_pf_status.ncounters[NCNT_FRAG_INSERT], 1);
|
||||
|
||||
if (frag->fr_firstoff[index] == NULL) {
|
||||
KASSERT(prev == NULL || pf_frent_index(prev) < index,
|
||||
@@ -496,6 +505,7 @@ pf_frent_remove(struct pf_fragment *frag, struct pf_frent *frent)
|
||||
}
|
||||
|
||||
TAILQ_REMOVE(&frag->fr_queue, frent, fr_next);
|
||||
counter_u64_add(V_pf_status.ncounters[NCNT_FRAG_REMOVALS], 1);
|
||||
|
||||
KASSERT(frag->fr_entries[index] > 0, ("No fragments remaining"));
|
||||
frag->fr_entries[index]--;
|
||||
@@ -768,6 +778,7 @@ pf_join_fragment(struct pf_fragment *frag)
|
||||
|
||||
frent = TAILQ_FIRST(&frag->fr_queue);
|
||||
TAILQ_REMOVE(&frag->fr_queue, frent, fr_next);
|
||||
counter_u64_add(V_pf_status.ncounters[NCNT_FRAG_REMOVALS], 1);
|
||||
|
||||
m = frent->fe_m;
|
||||
if ((frent->fe_hdrlen + frent->fe_len) < m->m_pkthdr.len)
|
||||
@@ -775,6 +786,7 @@ pf_join_fragment(struct pf_fragment *frag)
|
||||
uma_zfree(V_pf_frent_z, frent);
|
||||
while ((frent = TAILQ_FIRST(&frag->fr_queue)) != NULL) {
|
||||
TAILQ_REMOVE(&frag->fr_queue, frent, fr_next);
|
||||
counter_u64_add(V_pf_status.ncounters[NCNT_FRAG_REMOVALS], 1);
|
||||
|
||||
m2 = frent->fe_m;
|
||||
/* Strip off ip header. */
|
||||
|
||||
Reference in New Issue
Block a user