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 #include #include +#include #include #include @@ -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 [operation]\n", progname); fprintf(fp, "\tclearstats clear port statistics\n" + "\tclip hold|release hold/release an address\n" + "\tclip list list the CLIP table\n" "\tcontext show an SGE context\n" "\tdumpstate dump chip state\n" "\tfilter [ ] ... 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;