svn commit: r328815 - head/sbin/etherswitchcfg
Adrian Chadd
adrian at FreeBSD.org
Fri Feb 2 22:08:36 UTC 2018
Author: adrian
Date: Fri Feb 2 22:08:35 2018
New Revision: 328815
URL: https://svnweb.freebsd.org/changeset/base/328815
Log:
[etherswitchcfg] add atu flush and atu dump commands.
Extend the argc/argv handling to include variable length commands (like flush all,
flush port X).
Modified:
head/sbin/etherswitchcfg/etherswitchcfg.c
Modified: head/sbin/etherswitchcfg/etherswitchcfg.c
==============================================================================
--- head/sbin/etherswitchcfg/etherswitchcfg.c Fri Feb 2 22:08:03 2018 (r328814)
+++ head/sbin/etherswitchcfg/etherswitchcfg.c Fri Feb 2 22:08:35 2018 (r328815)
@@ -63,7 +63,8 @@ enum cmdmode {
MODE_CONFIG,
MODE_VLANGROUP,
MODE_REGISTER,
- MODE_PHYREG
+ MODE_PHYREG,
+ MODE_ATU
};
struct cfg {
@@ -79,9 +80,9 @@ struct cfg {
struct cmds {
enum cmdmode mode;
- const char *name;
- int args;
- void (*f)(struct cfg *, char *argv[]);
+ const char *name;
+ int args;
+ int (*f)(struct cfg *, int argc, char *argv[]);
};
static struct cmds cmds[];
@@ -166,12 +167,15 @@ write_phyregister(struct cfg *cfg, int phy, int reg, i
err(EX_OSERR, "ioctl(IOETHERSWITCHSETPHYREG)");
}
-static void
-set_port_vid(struct cfg *cfg, char *argv[])
+static int
+set_port_vid(struct cfg *cfg, int argc, char *argv[])
{
int v;
etherswitch_port_t p;
-
+
+ if (argc < 2)
+ return (-1);
+
v = strtol(argv[1], NULL, 0);
if (v < 0 || v > IEEE802DOT1Q_VID_MAX)
errx(EX_USAGE, "pvid must be between 0 and %d",
@@ -183,16 +187,20 @@ set_port_vid(struct cfg *cfg, char *argv[])
p.es_pvid = v;
if (ioctl(cfg->fd, IOETHERSWITCHSETPORT, &p) != 0)
err(EX_OSERR, "ioctl(IOETHERSWITCHSETPORT)");
+ return (0);
}
-static void
-set_port_flag(struct cfg *cfg, char *argv[])
+static int
+set_port_flag(struct cfg *cfg, int argc, char *argv[])
{
char *flag;
int n;
uint32_t f;
etherswitch_port_t p;
+ if (argc < 1)
+ return (-1);
+
n = 0;
f = 0;
flag = argv[0];
@@ -224,15 +232,19 @@ set_port_flag(struct cfg *cfg, char *argv[])
p.es_flags |= f;
if (ioctl(cfg->fd, IOETHERSWITCHSETPORT, &p) != 0)
err(EX_OSERR, "ioctl(IOETHERSWITCHSETPORT)");
+ return (0);
}
-static void
-set_port_media(struct cfg *cfg, char *argv[])
+static int
+set_port_media(struct cfg *cfg, int argc, char *argv[])
{
etherswitch_port_t p;
int ifm_ulist[IFMEDIAREQ_NULISTENTRIES];
int subtype;
-
+
+ if (argc < 2)
+ return (-1);
+
bzero(&p, sizeof(p));
p.es_port = cfg->unit;
p.es_ifmr.ifm_ulist = ifm_ulist;
@@ -240,21 +252,25 @@ set_port_media(struct cfg *cfg, char *argv[])
if (ioctl(cfg->fd, IOETHERSWITCHGETPORT, &p) != 0)
err(EX_OSERR, "ioctl(IOETHERSWITCHGETPORT)");
if (p.es_ifmr.ifm_count == 0)
- return;
+ return (0);
subtype = get_media_subtype(IFM_TYPE(ifm_ulist[0]), argv[1]);
p.es_ifr.ifr_media = (p.es_ifmr.ifm_current & IFM_IMASK) |
IFM_TYPE(ifm_ulist[0]) | subtype;
if (ioctl(cfg->fd, IOETHERSWITCHSETPORT, &p) != 0)
err(EX_OSERR, "ioctl(IOETHERSWITCHSETPORT)");
+ return (0);
}
-static void
-set_port_mediaopt(struct cfg *cfg, char *argv[])
+static int
+set_port_mediaopt(struct cfg *cfg, int argc, char *argv[])
{
etherswitch_port_t p;
int ifm_ulist[IFMEDIAREQ_NULISTENTRIES];
int options;
-
+
+ if (argc < 2)
+ return (-1);
+
bzero(&p, sizeof(p));
p.es_port = cfg->unit;
p.es_ifmr.ifm_ulist = ifm_ulist;
@@ -271,15 +287,19 @@ set_port_mediaopt(struct cfg *cfg, char *argv[])
p.es_ifr.ifr_media |= options;
if (ioctl(cfg->fd, IOETHERSWITCHSETPORT, &p) != 0)
err(EX_OSERR, "ioctl(IOETHERSWITCHSETPORT)");
+ return (0);
}
-static void
-set_port_led(struct cfg *cfg, char *argv[])
+static int
+set_port_led(struct cfg *cfg, int argc, char *argv[])
{
etherswitch_port_t p;
int led;
int i;
-
+
+ if (argc < 3)
+ return (-1);
+
bzero(&p, sizeof(p));
p.es_port = cfg->unit;
if (ioctl(cfg->fd, IOETHERSWITCHGETPORT, &p) != 0)
@@ -303,14 +323,19 @@ set_port_led(struct cfg *cfg, char *argv[])
if (ioctl(cfg->fd, IOETHERSWITCHSETPORT, &p) != 0)
err(EX_OSERR, "ioctl(IOETHERSWITCHSETPORT)");
+
+ return (0);
}
-static void
-set_vlangroup_vid(struct cfg *cfg, char *argv[])
+static int
+set_vlangroup_vid(struct cfg *cfg, int argc, char *argv[])
{
int v;
etherswitch_vlangroup_t vg;
+ if (argc < 2)
+ return (-1);
+
memset(&vg, 0, sizeof(vg));
v = strtol(argv[1], NULL, 0);
if (v < 0 || v > IEEE802DOT1Q_VID_MAX)
@@ -321,16 +346,20 @@ set_vlangroup_vid(struct cfg *cfg, char *argv[])
vg.es_vid = v;
if (ioctl(cfg->fd, IOETHERSWITCHSETVLANGROUP, &vg) != 0)
err(EX_OSERR, "ioctl(IOETHERSWITCHSETVLANGROUP)");
+ return (0);
}
-static void
-set_vlangroup_members(struct cfg *cfg, char *argv[])
+static int
+set_vlangroup_members(struct cfg *cfg, int argc, char *argv[])
{
etherswitch_vlangroup_t vg;
int member, untagged;
char *c, *d;
int v;
+ if (argc < 2)
+ return (-1);
+
member = untagged = 0;
memset(&vg, 0, sizeof(vg));
if (strcmp(argv[1], "none") != 0) {
@@ -360,6 +389,7 @@ set_vlangroup_members(struct cfg *cfg, char *argv[])
vg.es_untagged_ports = untagged;
if (ioctl(cfg->fd, IOETHERSWITCHSETVLANGROUP, &vg) != 0)
err(EX_OSERR, "ioctl(IOETHERSWITCHSETVLANGROUP)");
+ return (0);
}
static int
@@ -402,11 +432,14 @@ set_phyregister(struct cfg *cfg, char *arg)
return (0);
}
-static void
-set_vlan_mode(struct cfg *cfg, char *argv[])
+static int
+set_vlan_mode(struct cfg *cfg, int argc, char *argv[])
{
etherswitch_conf_t conf;
+ if (argc < 2)
+ return (-1);
+
bzero(&conf, sizeof(conf));
conf.cmd = ETHERSWITCH_CONF_VLAN_MODE;
if (strcasecmp(argv[1], "isl") == 0)
@@ -423,8 +456,71 @@ set_vlan_mode(struct cfg *cfg, char *argv[])
conf.vlan_mode = 0;
if (ioctl(cfg->fd, IOETHERSWITCHSETCONF, &conf) != 0)
err(EX_OSERR, "ioctl(IOETHERSWITCHSETCONF)");
+
+ return (0);
}
+static int
+atu_flush(struct cfg *cfg, int argc, char *argv[])
+{
+ etherswitch_portid_t p;
+ int i, r;
+
+ bzero(&p, sizeof(p));
+
+ /* note: argv[0] is "flush" */
+ if (argc > 2 && strcasecmp(argv[1], "port") == 0) {
+ p.es_port = atoi(argv[2]);
+ i = IOETHERSWITCHFLUSHPORT;
+ r = 3;
+ } else if (argc > 1 && strcasecmp(argv[1], "all") == 0) {
+ p.es_port = 0;
+ r = 2;
+ i = IOETHERSWITCHFLUSHALL;
+ } else {
+ fprintf(stderr,
+ "%s: invalid verb (port <x> or all) (got %s)\n",
+ __func__, argv[1]);
+ return (-1);
+ }
+
+ if (ioctl(cfg->fd, i, &p) != 0)
+ err(EX_OSERR, "ioctl(ATU flush (ioctl %d, port %d))",
+ i, p.es_port);
+ return (r);
+}
+
+static int
+atu_dump(struct cfg *cfg, int argc, char *argv[])
+{
+ etherswitch_atu_table_t p;
+ etherswitch_atu_entry_t e;
+ uint32_t i;
+
+ (void) argc;
+ (void) argv;
+
+ /* Note: argv[0] is "dump" */
+ bzero(&p, sizeof(p));
+
+ if (ioctl(cfg->fd, IOETHERSWITCHGETTABLE, &p) != 0)
+ err(EX_OSERR, "ioctl(IOETHERSWITCHGETTABLE)");
+
+ /* And now, iterate to get entries */
+ for (i = 0; i < p.es_nitems; i++) {
+ bzero(&e, sizeof(e));
+ e.id = i;
+ if (ioctl(cfg->fd, IOETHERSWITCHGETTABLEENTRY, &e) != 0)
+ break;
+
+ printf(" [%d] %s: portmask 0x%08x\n", i,
+ ether_ntoa((void *) &e.es_macaddr),
+ e.es_portmask);
+ }
+
+ return (1);
+}
+
static void
print_config(struct cfg *cfg)
{
@@ -619,6 +715,7 @@ newmode(struct cfg *cfg, enum cmdmode mode)
break;
case MODE_REGISTER:
case MODE_PHYREG:
+ case MODE_ATU:
break;
}
cfg->mode = mode;
@@ -686,6 +783,8 @@ main(int argc, char *argv[])
newmode(&cfg, MODE_REGISTER);
} else if (strcmp(argv[0], "help") == 0) {
usage(&cfg, argv);
+ } else if (strcmp(argv[0], "atu") == 0) {
+ newmode(&cfg, MODE_ATU);
} else {
errx(EX_USAGE, "Unknown command \"%s\"", argv[0]);
}
@@ -693,15 +792,33 @@ main(int argc, char *argv[])
case MODE_PORT:
case MODE_CONFIG:
case MODE_VLANGROUP:
+ case MODE_ATU:
for(i=0; cmds[i].name != NULL; i++) {
- if (cfg.mode == cmds[i].mode && strcmp(argv[0], cmds[i].name) == 0) {
- if (argc < (cmds[i].args + 1)) {
- printf("%s needs %d argument%s\n", cmds[i].name, cmds[i].args, (cmds[i].args==1)?"":",");
+ int r;
+ if (cfg.mode == cmds[i].mode &&
+ strcmp(argv[0], cmds[i].name) == 0) {
+ if ((cmds[i].args != -1) &&
+ (argc < (cmds[i].args + 1))) {
+ printf("%s needs %d argument%s\n",
+ cmds[i].name, cmds[i].args,
+ (cmds[i].args==1)?"":",");
break;
}
- (cmds[i].f)(&cfg, argv);
- argc -= cmds[i].args;
- argv += cmds[i].args;
+
+ r = (cmds[i].f)(&cfg, argc, argv);
+
+ /* -1 here means "error" */
+ if (r == -1) {
+ argc = 0;
+ break;
+ }
+
+ /* Legacy return value */
+ if (r == 0)
+ r = cmds[i].args;
+
+ argc -= r;
+ argv += r;
break;
}
}
@@ -752,5 +869,7 @@ static struct cmds cmds[] = {
{ MODE_CONFIG, "vlan_mode", 1, set_vlan_mode },
{ MODE_VLANGROUP, "vlan", 1, set_vlangroup_vid },
{ MODE_VLANGROUP, "members", 1, set_vlangroup_members },
+ { MODE_ATU, "flush", -1, atu_flush },
+ { MODE_ATU, "dump", -1, atu_dump },
{ 0, NULL, 0, NULL }
};
More information about the svn-src-all
mailing list