@@ -37,6 +37,7 @@ static void usage(void)
" bridge vlan { set } vid VLAN_ID dev DEV [ state STP_STATE ]\n"
" bridge vlan { show } [ dev DEV ] [ vid VLAN_ID ]\n"
" bridge vlan { tunnelshow } [ dev DEV ] [ vid VLAN_ID ]\n"
+ " bridge vlan global { set } vid VLAN_ID dev DEV\n"
" bridge vlan global { show } [ dev DEV ] [ vid VLAN_ID ]\n");
exit(-1);
}
@@ -338,6 +339,83 @@ static int vlan_option_set(int argc, char **argv)
return 0;
}
+static int vlan_global_option_set(int argc, char **argv)
+{
+ struct {
+ struct nlmsghdr n;
+ struct br_vlan_msg bvm;
+ char buf[1024];
+ } req = {
+ .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct br_vlan_msg)),
+ .n.nlmsg_flags = NLM_F_REQUEST,
+ .n.nlmsg_type = RTM_NEWVLAN,
+ .bvm.family = PF_BRIDGE,
+ };
+ struct rtattr *afspec;
+ short vid_end = -1;
+ char *d = NULL;
+ short vid = -1;
+
+ afspec = addattr_nest(&req.n, sizeof(req),
+ BRIDGE_VLANDB_GLOBAL_OPTIONS);
+ afspec->rta_type |= NLA_F_NESTED;
+ while (argc > 0) {
+ if (strcmp(*argv, "dev") == 0) {
+ NEXT_ARG();
+ d = *argv;
+ req.bvm.ifindex = ll_name_to_index(d);
+ if (req.bvm.ifindex == 0) {
+ fprintf(stderr, "Cannot find network device \"%s\"\n",
+ d);
+ return -1;
+ }
+ } else if (strcmp(*argv, "vid") == 0) {
+ char *p;
+
+ NEXT_ARG();
+ p = strchr(*argv, '-');
+ if (p) {
+ *p = '\0';
+ p++;
+ vid = atoi(*argv);
+ vid_end = atoi(p);
+ if (vid >= vid_end || vid_end >= 4096) {
+ fprintf(stderr, "Invalid VLAN range \"%hu-%hu\"\n",
+ vid, vid_end);
+ return -1;
+ }
+ } else {
+ vid = atoi(*argv);
+ }
+ if (vid >= 4096) {
+ fprintf(stderr, "Invalid VLAN ID \"%hu\"\n",
+ vid);
+ return -1;
+ }
+ addattr16(&req.n, sizeof(req), BRIDGE_VLANDB_GOPTS_ID,
+ vid);
+ if (vid_end != -1)
+ addattr16(&req.n, sizeof(req),
+ BRIDGE_VLANDB_GOPTS_RANGE, vid_end);
+ } else {
+ if (matches(*argv, "help") == 0)
+ NEXT_ARG();
+ }
+ argc--; argv++;
+ }
+ addattr_nest_end(&req.n, afspec);
+
+ if (d == NULL || vid == -1) {
+ fprintf(stderr, "Device and VLAN ID are required arguments.\n");
+ return -1;
+ }
+
+ if (rtnl_talk(&rth, &req.n, NULL) < 0)
+ return -1;
+
+ return 0;
+}
+
/* In order to use this function for both filtering and non-filtering cases
* we need to make it a tristate:
* return -1 - if filtering we've gone over so don't continue
@@ -1016,6 +1094,8 @@ static int vlan_global(int argc, char **argv)
matches(*argv, "lst") == 0 ||
matches(*argv, "list") == 0)
return vlan_global_show(argc-1, argv+1);
+ else if (matches(*argv, "set") == 0)
+ return vlan_global_option_set(argc-1, argv+1);
else
usage();
} else {
@@ -152,6 +152,13 @@ bridge \- show / manipulate bridge addresses and devices
.B dev
.IR DEV " ]"
+.ti -8
+.BR "bridge vlan global set"
+.B dev
+.I DEV
+.B vid
+.IR VID " [ ]"
+
.ti -8
.BR "bridge vlan global" " [ " show " ] [ "
.B dev
@@ -902,6 +909,19 @@ option, the command displays per-vlan traffic statistics.
This command displays the current vlan tunnel info mapping.
+.SS bridge vlan global set - change vlan filter entry's global options
+
+This command changes vlan filter entry's global options.
+
+.TP
+.BI dev " NAME"
+the interface with which this vlan is associated. Only bridge devices are
+supported for global options.
+
+.TP
+.BI vid " VID"
+the VLAN ID that identifies the vlan.
+
.SS bridge vlan global show - list global vlan options.
This command displays the global VLAN options for each VLAN entry.