]> git.proxmox.com Git - mirror_iproute2.git/commitdiff
iproute2: bridge: support vlan range adds
authorRoopa Prabhu <roopa@cumulusnetworks.com>
Mon, 26 Jan 2015 02:26:24 +0000 (18:26 -0800)
committerStephen Hemminger <shemming@brocade.com>
Thu, 5 Feb 2015 18:46:31 +0000 (10:46 -0800)
This patch adds vlan range support to bridge add command
using the newly added vinfo flags BRIDGE_VLAN_INFO_RANGE_BEGIN and
BRIDGE_VLAN_INFO_RANGE_END.

$bridge vlan show
port    vlan ids
br0      1 PVID Egress Untagged

dummy0   1 PVID Egress Untagged

$bridge vlan add vid 10-15 dev dummy0
port    vlan ids
br0      1 PVID Egress Untagged

dummy0   1 PVID Egress Untagged
         10
         11
         12
         13
         14
         15

$bridge vlan del vid 14 dev dummy0

$bridge vlan show
port    vlan ids
br0      1 PVID Egress Untagged

dummy0   1 PVID Egress Untagged
         10
         11
         12
         13
         15

$bridge vlan del vid 10-15 dev dummy0

$bridge vlan show
port    vlan ids
br0      1 PVID Egress Untagged

dummy0   1 PVID Egress Untagged

Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Signed-off-by: Wilson Kok <wkok@cumulusnetworks.com>
bridge/vlan.c

index 3bd7b0db5090d37b5f144ec3cfb732e820234f7e..88992e6330f769134e8e15ea0c1362c4c69bf5f7 100644 (file)
@@ -32,6 +32,7 @@ static int vlan_modify(int cmd, int argc, char **argv)
        } req;
        char *d = NULL;
        short vid = -1;
+       short vid_end = -1;
        struct rtattr *afspec;
        struct bridge_vlan_info vinfo;
        unsigned short flags = 0;
@@ -49,8 +50,18 @@ static int vlan_modify(int cmd, int argc, char **argv)
                        NEXT_ARG();
                        d = *argv;
                } else if (strcmp(*argv, "vid") == 0) {
+                       char *p;
                        NEXT_ARG();
-                       vid = atoi(*argv);
+                       p = strchr(*argv, '-');
+                       if (p) {
+                               *p = '\0';
+                               p++;
+                               vid = atoi(*argv);
+                               vid_end = atoi(p);
+                               vinfo.flags |= BRIDGE_VLAN_INFO_RANGE_BEGIN;
+                       } else {
+                               vid = atoi(*argv);
+                       }
                } else if (strcmp(*argv, "self") == 0) {
                        flags |= BRIDGE_FLAGS_SELF;
                } else if (strcmp(*argv, "master") == 0) {
@@ -83,15 +94,40 @@ static int vlan_modify(int cmd, int argc, char **argv)
                return -1;
        }
 
-       vinfo.vid = vid;
+       if (vinfo.flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) {
+               if (vid_end == -1 || vid_end >= 4096 || vid >= vid_end) {
+                       fprintf(stderr, "Invalid VLAN range \"%hu-%hu\"\n",
+                               vid, vid_end);
+                       return -1;
+               }
+               if (vinfo.flags & BRIDGE_VLAN_INFO_PVID) {
+                       fprintf(stderr,
+                               "pvid cannot be configured for a vlan range\n");
+                       return -1;
+               }
+       }
 
        afspec = addattr_nest(&req.n, sizeof(req), IFLA_AF_SPEC);
 
        if (flags)
                addattr16(&req.n, sizeof(req), IFLA_BRIDGE_FLAGS, flags);
 
-       addattr_l(&req.n, sizeof(req), IFLA_BRIDGE_VLAN_INFO, &vinfo,
-                 sizeof(vinfo));
+       vinfo.vid = vid;
+       if (vid_end != -1) {
+               /* send vlan range start */
+               addattr_l(&req.n, sizeof(req), IFLA_BRIDGE_VLAN_INFO, &vinfo,
+                         sizeof(vinfo));
+               vinfo.flags &= ~BRIDGE_VLAN_INFO_RANGE_BEGIN;
+
+               /* Now send the vlan range end */
+               vinfo.flags |= BRIDGE_VLAN_INFO_RANGE_END;
+               vinfo.vid = vid_end;
+               addattr_l(&req.n, sizeof(req), IFLA_BRIDGE_VLAN_INFO, &vinfo,
+                         sizeof(vinfo));
+       } else {
+               addattr_l(&req.n, sizeof(req), IFLA_BRIDGE_VLAN_INFO, &vinfo,
+                         sizeof(vinfo));
+       }
 
        addattr_nest_end(&req.n, afspec);