git: be259947759b - stable/13 - cxgbetool(8): add a 'clip' subcommand to deal with the CLIP table.

From: Navdeep Parhar <np_at_FreeBSD.org>
Date: Wed, 20 Oct 2021 17:27:05 UTC
The branch stable/13 has been updated by np:

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

commit be259947759be3c677e022ec314625812e7cb837
Author:     Navdeep Parhar <np@FreeBSD.org>
AuthorDate: 2021-05-23 23:28:31 +0000
Commit:     Navdeep Parhar <np@FreeBSD.org>
CommitDate: 2021-10-20 17:12:37 +0000

    cxgbetool(8): add a 'clip' subcommand to deal with the CLIP table.
    
    Sponsored by:   Chelsio Communications
    
    (cherry picked from commit ac02945f7e2b5ab84fe510fc052c35350e31220d)
---
 usr.sbin/cxgbetool/cxgbetool.8 | 30 ++++++++++++++-
 usr.sbin/cxgbetool/cxgbetool.c | 84 ++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 110 insertions(+), 4 deletions(-)

diff --git a/usr.sbin/cxgbetool/cxgbetool.8 b/usr.sbin/cxgbetool/cxgbetool.8
index 56980e42795f..02dc1a176eb0 100644
--- a/usr.sbin/cxgbetool/cxgbetool.8
+++ b/usr.sbin/cxgbetool/cxgbetool.8
@@ -31,7 +31,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd Sep 21, 2018
+.Dd May 23, 2021
 .Dt CXGBETOOL 8
 .Os
 .Sh NAME
@@ -46,6 +46,10 @@
 .It
 .Nm Ar nexus Cm clearstats Ar port_id
 .It
+.Nm Ar nexus Cm clip Bro Cm hold | release Brc Ar ipv6-address
+.It
+.Nm Ar nexus Cm clip Cm list
+.It
 .Nm Ar nexus Cm context Bro Cm ingress | egress | fl | cong Brc Ar cntxt_id
 .It
 .Nm Ar nexus Cm hashfilter mode
@@ -119,6 +123,30 @@ identifies a port within this range.
 .Pp
 .Bl -item -compact
 .It
+.Cm clip hold Ar ipv6-address
+.El
+Install a reference on the given
+.Ar ipv6-address
+in the CLIP (Compressed Local IPv6) table.
+The address is added to the CLIP table if it is not present there already.
+.Pp
+.Bl -item -compact
+.It
+.Cm clip list
+.El
+List the contents of the CLIP table.
+.Pp
+.Bl -item -compact
+.It
+.Cm clip release Ar ipv6-address
+.El
+Release a reference on the given
+.Ar ipv6-address
+in the CLIP table.
+A reference on the address must have been acquired previously.
+.Pp
+.Bl -item -compact
+.It
 .Cm context ingress Ar ingress_cntxt_id
 .It
 .Cm context cong Ar ingress_cntxt_id
diff --git a/usr.sbin/cxgbetool/cxgbetool.c b/usr.sbin/cxgbetool/cxgbetool.c
index 139a0bd8e564..77f092123de9 100644
--- a/usr.sbin/cxgbetool/cxgbetool.c
+++ b/usr.sbin/cxgbetool/cxgbetool.c
@@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/mman.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
+#include <sys/sysctl.h>
 
 #include <arpa/inet.h>
 #include <net/ethernet.h>
@@ -58,7 +59,8 @@ __FBSDID("$FreeBSD$");
 #define	max(x, y) ((x) > (y) ? (x) : (y))
 
 static const char *progname, *nexus;
-static int chip_id;	/* 4 for T4, 5 for T5 */
+static int chip_id;	/* 4 for T4, 5 for T5, and so on. */
+static int inst;	/* instance of nexus device */
 
 struct reg_info {
 	const char *name;
@@ -91,6 +93,8 @@ usage(FILE *fp)
 	fprintf(fp, "Usage: %s <nexus> [operation]\n", progname);
 	fprintf(fp,
 	    "\tclearstats <port>                   clear port statistics\n"
+	    "\tclip hold|release <ip6>             hold/release an address\n"
+	    "\tclip list                           list the CLIP table\n"
 	    "\tcontext <type> <id>                 show an SGE context\n"
 	    "\tdumpstate <dump.bin>                dump chip state\n"
 	    "\tfilter <idx> [<param> <val>] ...    set a filter\n"
@@ -3506,6 +3510,69 @@ load_offload_policy(int argc, const char *argv[])
 	return (rc);
 }
 
+static int
+display_clip(void)
+{
+	size_t clip_buf_size = 4096;
+	char *buf, name[32];
+	int rc;
+
+	buf = malloc(clip_buf_size);
+	if (buf == NULL) {
+		warn("%s", __func__);
+		return (errno);
+	}
+
+	snprintf(name, sizeof(name), "dev.t%unex.%u.misc.clip", chip_id, inst);
+	rc = sysctlbyname(name, buf, &clip_buf_size, NULL, 0);
+	if (rc != 0) {
+		warn("sysctl %s", name);
+		free(buf);
+		return (errno);
+	}
+
+	printf("%s\n", buf);
+	free(buf);
+	return (0);
+}
+
+static int
+clip_cmd(int argc, const char *argv[])
+{
+	int rc, af = AF_INET6, add;
+	struct t4_clip_addr ca = {0};
+
+	if (argc == 1 && !strcmp(argv[0], "list")) {
+		rc = display_clip();
+		return (rc);
+	}
+
+	if (argc != 2) {
+		warnx("incorrect number of arguments.");
+		return (EINVAL);
+	}
+
+	if (!strcmp(argv[0], "hold")) {
+		add = 1;
+	} else if (!strcmp(argv[0], "rel") || !strcmp(argv[0], "release")) {
+		add = 0;
+	} else {
+		warnx("first argument must be \"hold\" or \"release\"");
+		return (EINVAL);
+	}
+
+	rc = parse_ipaddr(argv[0], argv, &af, &ca.addr[0], &ca.mask[0], 1);
+	if (rc != 0)
+		return (rc);
+
+	if (add)
+		rc = doit(CHELSIO_T4_HOLD_CLIP_ADDR, &ca);
+	else
+		rc = doit(CHELSIO_T4_RELEASE_CLIP_ADDR, &ca);
+
+	return (rc);
+}
+
 static int
 run_cmd(int argc, const char *argv[])
 {
@@ -3556,6 +3623,8 @@ run_cmd(int argc, const char *argv[])
 		rc = load_offload_policy(argc, argv);
 	else if (!strcmp(cmd, "hashfilter"))
 		rc = filter_cmd(argc, argv, 1);
+	else if (!strcmp(cmd, "clip"))
+		rc = clip_cmd(argc, argv);
 	else {
 		rc = EINVAL;
 		warnx("invalid command \"%s\"", cmd);
@@ -3609,6 +3678,16 @@ run_cmd_loop(void)
 	return (rc);
 }
 
+static void
+parse_nexus_name(const char *s)
+{
+	char junk;
+
+	if (sscanf(s, "t%unex%u%c", &chip_id, &inst, &junk) != 2)
+		errx(EINVAL, "invalid nexus \"%s\"", s);
+	nexus = s;
+}
+
 int
 main(int argc, const char *argv[])
 {
@@ -3628,8 +3707,7 @@ main(int argc, const char *argv[])
 		exit(EINVAL);
 	}
 
-	nexus = argv[1];
-	chip_id = nexus[1] - '0';
+	parse_nexus_name(argv[1]);
 
 	/* progname and nexus */
 	argc -= 2;