Index | Thread | Search

From:
Claudio Jeker <cjeker@diehard.n-r-g.com>
Subject:
Re: pfctl show fragment info
To:
Alexander Bluhm <bluhm@openbsd.org>
Cc:
tech@openbsd.org
Date:
Fri, 19 Apr 2024 20:12:08 +0200

Download raw body.

Thread
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