git: e95025ed9388 - main - pflow: show socket status in verbose mode

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Thu, 25 Jan 2024 17:08:24 UTC
The branch main has been updated by kp:

URL: https://cgit.FreeBSD.org/src/commit/?id=e95025ed93886dc854c2c92a2d2812cb51abf4ed

commit e95025ed93886dc854c2c92a2d2812cb51abf4ed
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2024-01-25 16:37:51 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2024-01-25 16:37:51 +0000

    pflow: show socket status in verbose mode
    
    Introduce a verbose output mode to pflowctl, and expose the status of
    the socket to userspace. This can be helpful in debugging configuration
    errors.
    
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
---
 sbin/pflowctl/pflowctl.8 |  5 ++++-
 sbin/pflowctl/pflowctl.c | 52 ++++++++++++++++++++++++++++++++++++++++++------
 sys/net/pflow.h          |  3 ++-
 sys/netpfil/pf/pflow.c   |  1 +
 4 files changed, 53 insertions(+), 8 deletions(-)

diff --git a/sbin/pflowctl/pflowctl.8 b/sbin/pflowctl/pflowctl.8
index 446679486db6..8c4142f31396 100644
--- a/sbin/pflowctl/pflowctl.8
+++ b/sbin/pflowctl/pflowctl.8
@@ -15,7 +15,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: January 08 2024 $
+.Dd $Mdocdate: January 25 2024 $
 .Dt PFLOWCTL 8
 .Os
 .Sh NAME
@@ -24,6 +24,7 @@
 .Sh SYNOPSIS
 .Nm pflowctl
 .Bk -words
+.Op Fl v
 .Op Fl lc
 .Op Fl d Ar id
 .Op Fl s Ar id ...
@@ -40,6 +41,8 @@ The
 utility provides several commands.
 The options are as follows:
 .Bl -tag -width Ds
+.It Fl v
+Produce verbose output.
 .It Fl c
 Create a new
 .Xr pflow 4
diff --git a/sbin/pflowctl/pflowctl.c b/sbin/pflowctl/pflowctl.c
index e5dd3df7e6a7..f6ca8980db1b 100644
--- a/sbin/pflowctl/pflowctl.c
+++ b/sbin/pflowctl/pflowctl.c
@@ -47,13 +47,15 @@
 
 static int get(int id);
 
+static bool verbose = false;
+
 extern char *__progname;
 
 static void
 usage(void)
 {
 	fprintf(stderr,
-"usage: %s [-lc] [-d id] [-s id ...]\n",
+"usage: %s [-lc] [-d id] [-s id ...] [-v]\n",
 	    __progname);
 
 	exit(1);
@@ -253,6 +255,7 @@ struct pflowctl_get {
 	struct pflowctl_sockaddr src;
 	struct pflowctl_sockaddr dst;
 	uint32_t obs_dom;
+	uint8_t so_status;
 };
 #define	_IN(_field)	offsetof(struct genlmsghdr, _field)
 #define	_OUT(_field)	offsetof(struct pflowctl_get, _field)
@@ -262,6 +265,7 @@ static struct snl_attr_parser ap_get[] = {
 	{ .type = PFLOWNL_GET_SRC, .off = _OUT(src), .arg = &sockaddr_parser, .cb = snl_attr_get_nested },
 	{ .type = PFLOWNL_GET_DST, .off = _OUT(dst), .arg = &sockaddr_parser, .cb = snl_attr_get_nested },
 	{ .type = PFLOWNL_GET_OBSERVATION_DOMAIN, .off = _OUT(obs_dom), .cb = snl_attr_get_uint32 },
+	{ .type = PFLOWNL_GET_SOCKET_STATUS, .off = _OUT(so_status), .cb = snl_attr_get_uint8 },
 };
 static struct snl_field_parser fp_get[] = {};
 #undef _IN
@@ -344,6 +348,10 @@ get(int id)
 		print_sockaddr(" src ", &g.src.storage);
 		print_sockaddr(" dst ", &g.dst.storage);
 		printf("\n");
+		if (verbose) {
+			printf("\tsocket: %s\n",
+			    g.so_status ? "connected" : "disconnected");
+		}
 	}
 
 	if (e.error)
@@ -533,10 +541,20 @@ static const struct snl_hdr_parser *all_parsers[] = {
 	&get_parser,
 };
 
+enum pflowctl_op_t {
+	OP_HELP,
+	OP_LIST,
+	OP_CREATE,
+	OP_DELETE,
+	OP_SET,
+};
 int
 main(int argc, char *argv[])
 {
 	int ch;
+	enum pflowctl_op_t op = OP_HELP;
+	char **set_args = NULL;
+	size_t set_arg_count = 0;
 
 	SNL_VERIFY_PARSERS(all_parsers);
 
@@ -544,18 +562,40 @@ main(int argc, char *argv[])
 		usage();
 
 	while ((ch = getopt(argc, argv,
-	    "lcd:s:")) != -1) {
+	    "lcd:s:v")) != -1) {
 		switch (ch) {
 		case 'l':
-			return (list());
+			op = OP_LIST;
+			break;
 		case 'c':
-			return (create());
+			op = OP_CREATE;
+			break;
 		case 'd':
-			return (del(optarg));
+			op = OP_DELETE;
+			break;
 		case 's':
-			return (set(optarg, argc - optind, argv + optind));
+			op = OP_SET;
+			set_arg_count = argc - optind;
+			set_args = argv + optind;
+		case 'v':
+			verbose = true;
+			break;
 		}
 	}
 
+	switch (op) {
+	case OP_LIST:
+		return (list());
+	case OP_CREATE:
+		return (create());
+	case OP_DELETE:
+		return (del(optarg));
+	case OP_SET:
+		return (set(optarg, set_arg_count, set_args));
+	case OP_HELP:
+		usage();
+		break;
+	}
+
 	return (0);
 }
diff --git a/sys/net/pflow.h b/sys/net/pflow.h
index 4c194e14e001..ee747d1a6a46 100644
--- a/sys/net/pflow.h
+++ b/sys/net/pflow.h
@@ -362,7 +362,8 @@ enum pflow_get_type_t {
 	PFLOWNL_GET_VERSION	= 2, /* u16 */
 	PFLOWNL_GET_SRC		= 3, /* struct sockaddr_storage */
 	PFLOWNL_GET_DST		= 4, /* struct sockaddr_storage */
-	PFLOWNL_GET_OBSERVATION_DOMAIN = 5, /* u32 */
+	PFLOWNL_GET_OBSERVATION_DOMAIN	= 5, /* u32 */
+	PFLOWNL_GET_SOCKET_STATUS	= 6, /* u8 */
 };
 
 enum pflow_set_type_t {
diff --git a/sys/netpfil/pf/pflow.c b/sys/netpfil/pf/pflow.c
index 17a68e0d9e57..f3dba7687d05 100644
--- a/sys/netpfil/pf/pflow.c
+++ b/sys/netpfil/pf/pflow.c
@@ -1485,6 +1485,7 @@ pflow_nl_get(struct nlmsghdr *hdr, struct nl_pstate *npt)
 		nlattr_add_sockaddr(nw, PFLOWNL_GET_DST, sc->sc_flowdst);
 	nlattr_add_u32(nw, PFLOWNL_GET_OBSERVATION_DOMAIN,
 	    sc->sc_observation_dom);
+	nlattr_add_u8(nw, PFLOWNL_GET_SOCKET_STATUS, sc->so != NULL);
 
 	if (! nlmsg_end(nw)) {
 		nlmsg_abort(nw);