]> git.proxmox.com Git - mirror_iproute2.git/blobdiff - bridge/vlan.c
libnetlink: add size argument to rtnl_talk
[mirror_iproute2.git] / bridge / vlan.c
index 83c40880f0425ac5407fa444bbcbbbb6b1849f56..ac2f52311ea492165752a5431805b4439650fbe0 100644 (file)
@@ -13,7 +13,7 @@
 #include "br_common.h"
 #include "utils.h"
 
-int filter_index;
+static unsigned int filter_index;
 
 static void usage(void)
 {
@@ -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) {
@@ -69,7 +80,7 @@ static int vlan_modify(int cmd, int argc, char **argv)
 
        if (d == NULL || vid == -1) {
                fprintf(stderr, "Device and VLAN ID are required arguments.\n");
-               exit(-1);
+               return -1;
        }
 
        req.ifm.ifi_index = ll_name_to_index(d);
@@ -83,20 +94,45 @@ 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);
 
-       if (rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0)
-               exit(2);
+       if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
+               return -1;
 
        return 0;
 }
@@ -146,7 +182,12 @@ static int print_vlan(const struct sockaddr_nl *who,
                                continue;
 
                        vinfo = RTA_DATA(i);
-                       fprintf(fp, "\t %hu", vinfo->vid);
+                       if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_END)
+                               fprintf(fp, "-%hu", vinfo->vid);
+                       else
+                               fprintf(fp, "\t %hu", vinfo->vid);
+                       if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN)
+                               continue;
                        if (vinfo->flags & BRIDGE_VLAN_INFO_PVID)
                                fprintf(fp, " PVID");
                        if (vinfo->flags & BRIDGE_VLAN_INFO_UNTAGGED)
@@ -182,7 +223,9 @@ static int vlan_show(int argc, char **argv)
        }
 
        if (rtnl_wilddump_req_filter(&rth, PF_BRIDGE, RTM_GETLINK,
-                                    RTEXT_FILTER_BRVLAN) < 0) {
+                                   (compress_vlans ?
+                                   RTEXT_FILTER_BRVLAN_COMPRESSED :
+                                   RTEXT_FILTER_BRVLAN)) < 0) {
                perror("Cannont send dump request");
                exit(1);
        }