mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-06 17:18:32 +00:00
[etherswitchcfg] add atu flush and atu dump commands.
Extend the argc/argv handling to include variable length commands (like flush all, flush port X).
This commit is contained in:
parent
84a5558c38
commit
138952cfc7
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=328815
|
@ -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, int val)
|
|||
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,6 +456,69 @@ 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
|
||||
|
@ -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 }
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue