From: Claudio Jeker Subject: Re: pfctl show fragment info To: Alexander Bluhm Cc: tech@openbsd.org Date: Fri, 19 Apr 2024 20:12:08 +0200 On Fri, Apr 19, 2024 at 07:43:05PM +0200, Alexander Bluhm wrote: > Hi, > > I would like to show pf fragment reassembly counters. > > # pfctl -si -v > ... > Fragments > current entries 26 > searches 1055 0.3/s > inserts 1037 0.3/s > removals 1011 0.3/s > > ok? Please also add it to systat(1) which uses sysctl and kern.pfstatus. > bluhm > > Index: sys/net/pf_ioctl.c > =================================================================== > RCS file: /data/mirror/openbsd/cvs/src/sys/net/pf_ioctl.c,v > diff -u -p -r1.415 pf_ioctl.c > --- sys/net/pf_ioctl.c 6 Jul 2023 04:55:05 -0000 1.415 > +++ sys/net/pf_ioctl.c 19 Apr 2024 13:28:39 -0000 > @@ -1955,6 +1955,11 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a > struct pf_status *s = (struct pf_status *)addr; > NET_LOCK(); > PF_LOCK(); > + PF_FRAG_LOCK(); > + pf_status.fragments = pf_nfrents; > + memcpy(pf_status.ncounters, pf_nfrentcounters, > + sizeof(pf_status.ncounters)); > + PF_FRAG_UNLOCK(); > memcpy(s, &pf_status, sizeof(struct pf_status)); > pfi_update_status(s->ifname, s); > PF_UNLOCK(); > Index: sys/net/pf_norm.c > =================================================================== > RCS file: /data/mirror/openbsd/cvs/src/sys/net/pf_norm.c,v > diff -u -p -r1.229 pf_norm.c > --- sys/net/pf_norm.c 10 Oct 2023 11:25:31 -0000 1.229 > +++ sys/net/pf_norm.c 19 Apr 2024 13:44:40 -0000 > @@ -150,13 +150,12 @@ int pf_reassemble6(struct mbuf **, st > /* Globals */ > struct pool pf_frent_pl, pf_frag_pl, pf_frnode_pl; > struct pool pf_state_scrub_pl; > -int pf_nfrents; > +uint32_t pf_nfrents; > +uint64_t pf_nfrentcounters[NCNT_MAX]; > > struct mutex pf_frag_mtx; > > #define PF_FRAG_LOCK_INIT() mtx_init(&pf_frag_mtx, IPL_SOFTNET) > -#define PF_FRAG_LOCK() mtx_enter(&pf_frag_mtx) > -#define PF_FRAG_UNLOCK() mtx_leave(&pf_frag_mtx) > > void > pf_normalize_init(void) > @@ -233,7 +232,7 @@ void > pf_flush_fragments(void) > { > struct pf_fragment *frag; > - int goal; > + u_int goal; > > goal = pf_nfrents * 9 / 10; > DPFPRINTF(LOG_NOTICE, "trying to free > %d frents", pf_nfrents - goal); > @@ -268,6 +267,7 @@ pf_free_fragment(struct pf_fragment *fra > /* Free all fragment entries */ > while ((frent = TAILQ_FIRST(&frag->fr_queue)) != NULL) { > TAILQ_REMOVE(&frag->fr_queue, frent, fr_next); > + pf_nfrentcounters[NCNT_FRAG_REMOVALS]++; > m_freem(frent->fe_m); > pool_put(&pf_frent_pl, frent); > pf_nfrents--; > @@ -283,6 +283,7 @@ pf_find_fragment(struct pf_frnode *key, > u_int32_t stale; > > frnode = RB_FIND(pf_frnode_tree, &pf_frnode_tree, key); > + pf_nfrentcounters[NCNT_FRAG_SEARCH]++; > if (frnode == NULL) > return (NULL); > KASSERT(frnode->fn_fragments >= 1); > @@ -405,6 +406,7 @@ pf_frent_insert(struct pf_fragment *frag > KASSERT(prev->fe_off + prev->fe_len <= frent->fe_off); > TAILQ_INSERT_AFTER(&frag->fr_queue, prev, frent, fr_next); > } > + pf_nfrentcounters[NCNT_FRAG_INSERT]++; > > if (frag->fr_firstoff[index] == NULL) { > KASSERT(prev == NULL || pf_frent_index(prev) < index); > @@ -456,6 +458,7 @@ pf_frent_remove(struct pf_fragment *frag > } > > TAILQ_REMOVE(&frag->fr_queue, frent, fr_next); > + pf_nfrentcounters[NCNT_FRAG_REMOVALS]++; > > KASSERT(frag->fr_entries[index] > 0); > frag->fr_entries[index]--; > @@ -742,6 +745,7 @@ pf_join_fragment(struct pf_fragment *fra > > frent = TAILQ_FIRST(&frag->fr_queue); > TAILQ_REMOVE(&frag->fr_queue, frent, fr_next); > + pf_nfrentcounters[NCNT_FRAG_REMOVALS]++; > > m = frent->fe_m; > /* Strip off any trailing bytes */ > @@ -756,6 +760,7 @@ pf_join_fragment(struct pf_fragment *fra > > while ((frent = TAILQ_FIRST(&frag->fr_queue)) != NULL) { > TAILQ_REMOVE(&frag->fr_queue, frent, fr_next); > + pf_nfrentcounters[NCNT_FRAG_REMOVALS]++; > m2 = frent->fe_m; > /* Strip off ip header */ > m_adj(m2, frent->fe_hdrlen); > Index: sys/net/pfvar.h > =================================================================== > RCS file: /data/mirror/openbsd/cvs/src/sys/net/pfvar.h,v > diff -u -p -r1.535 pfvar.h > --- sys/net/pfvar.h 1 Jan 2024 22:16:51 -0000 1.535 > +++ sys/net/pfvar.h 19 Apr 2024 13:03:26 -0000 > @@ -1192,6 +1192,11 @@ enum pfi_kif_refs { > #define SCNT_SRC_NODE_REMOVALS 2 > #define SCNT_MAX 3 > > +#define NCNT_FRAG_SEARCH 0 > +#define NCNT_FRAG_INSERT 1 > +#define NCNT_FRAG_REMOVALS 2 > +#define NCNT_MAX 3 > + > #define REASON_SET(a, x) \ > do { \ > if ((void *)(a) != NULL) { \ > @@ -1206,6 +1211,7 @@ struct pf_status { > u_int64_t lcounters[LCNT_MAX]; /* limit counters */ > u_int64_t fcounters[FCNT_MAX]; > u_int64_t scounters[SCNT_MAX]; > + u_int64_t ncounters[NCNT_MAX]; > u_int64_t pcounters[2][2][3]; > u_int64_t bcounters[2][2]; > u_int64_t stateid; > @@ -1215,6 +1221,7 @@ struct pf_status { > u_int32_t states; > u_int32_t states_halfopen; > u_int32_t src_nodes; > + u_int32_t fragments; > u_int32_t debug; > u_int32_t hostid; > u_int32_t reass; /* reassembly */ > Index: sys/net/pfvar_priv.h > =================================================================== > RCS file: /data/mirror/openbsd/cvs/src/sys/net/pfvar_priv.h,v > diff -u -p -r1.35 pfvar_priv.h > --- sys/net/pfvar_priv.h 1 Jan 2024 22:16:51 -0000 1.35 > +++ sys/net/pfvar_priv.h 19 Apr 2024 13:21:00 -0000 > @@ -368,8 +368,12 @@ extern struct timeout pf_purge_to; > struct pf_state *pf_state_ref(struct pf_state *); > void pf_state_unref(struct pf_state *); > > +extern uint32_t pf_nfrents; > +extern uint64_t pf_nfrentcounters[]; > + > extern struct rwlock pf_lock; > extern struct rwlock pf_state_lock; > +extern struct mutex pf_frag_mtx; > extern struct mutex pf_inp_mtx; > > #define PF_LOCK() do { \ > @@ -414,6 +418,9 @@ extern struct mutex pf_inp_mtx; > splassert_fail(RW_WRITE, \ > rw_status(&pf_state_lock), __func__);\ > } while (0) > + > +#define PF_FRAG_LOCK() mtx_enter(&pf_frag_mtx) > +#define PF_FRAG_UNLOCK() mtx_leave(&pf_frag_mtx) > > /* for copies to/from network byte order */ > void pf_state_peer_hton(const struct pf_state_peer *, > Index: sbin/pfctl/pfctl_parser.c > =================================================================== > RCS file: /data/mirror/openbsd/cvs/src/sbin/pfctl/pfctl_parser.c,v > diff -u -p -r1.350 pfctl_parser.c > --- sbin/pfctl/pfctl_parser.c 7 Feb 2024 23:53:44 -0000 1.350 > +++ sbin/pfctl/pfctl_parser.c 19 Apr 2024 12:53:03 -0000 > @@ -519,7 +519,8 @@ print_pool(struct pf_pool *pool, u_int16 > const char *pf_reasons[PFRES_MAX+1] = PFRES_NAMES; > const char *pf_lcounters[LCNT_MAX+1] = LCNT_NAMES; > const char *pf_fcounters[FCNT_MAX+1] = FCNT_NAMES; > -const char *pf_scounters[FCNT_MAX+1] = FCNT_NAMES; > +const char *pf_scounters[SCNT_MAX+1] = FCNT_NAMES; > +const char *pf_ncounters[NCNT_MAX+1] = FCNT_NAMES; > > void > print_status(struct pf_status *s, struct pfctl_watermarks *synflwats, int opts) > @@ -613,6 +614,20 @@ print_status(struct pf_status *s, struct > if (runtime > 0) > printf("%14.1f/s\n", > (double)s->scounters[i] / (double)runtime); > + else > + printf("%14s\n", ""); > + } > + } > + if (opts & PF_OPT_VERBOSE) { > + printf("Fragments\n"); > + printf(" %-25s %14u %14s\n", "current entries", > + s->fragments, ""); > + for (i = 0; i < NCNT_MAX; i++) { > + printf(" %-25s %14lld ", pf_ncounters[i], > + s->ncounters[i]); > + if (runtime > 0) > + printf("%14.1f/s\n", > + (double)s->ncounters[i] / (double)runtime); > else > printf("%14s\n", ""); > } > -- :wq Claudio