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 }
 };
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to