Index | Thread | Search

From:
Alexander Bluhm <bluhm@openbsd.org>
Subject:
pfctl show fragment info
To:
tech@openbsd.org
Date:
Fri, 19 Apr 2024 19:43:05 +0200

Download raw body.

Thread
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?

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", "");
 		}