@@ -118,6 +118,7 @@ enum {
IFLA_PORT_SELF,
IFLA_AF_SPEC,
IFLA_GROUP,
+ IFLA_FILTERGROUP,
__IFLA_MAX
};
@@ -151,5 +151,6 @@ extern int makeargs(char *line, char *argv[], int maxargs);
struct iplink_req;
int iplink_parse(int argc, char **argv, struct iplink_req *req,
- char **name, char **type, char **link, char **dev);
+ char **name, char **type, char **link, char **dev,
+ int *devgroup);
#endif /* __UTILS_H__ */
@@ -245,7 +245,8 @@ int iplink_parse_vf(int vf, int *argcp, char ***argvp,
int iplink_parse(int argc, char **argv, struct iplink_req *req,
- char **name, char **type, char **link, char **dev)
+ char **name, char **type, char **link, char **dev,
+ int *devgroup)
{
int ret, len;
char abuf[32];
@@ -256,6 +257,7 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
int group = -1;
ret = argc;
+ *devgroup = -1; /* Not set. */
while (argc > 0) {
if (strcmp(*argv, "up") == 0) {
@@ -395,6 +397,20 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
} else {
if (strcmp(*argv, "dev") == 0) {
NEXT_ARG();
+ if (*dev)
+ duparg2("dev", *argv);
+ *dev = *argv;
+ argc--; argv++;
+ continue;
+ }
+ if (matches(*argv, "devgroup") == 0) {
+ NEXT_ARG();
+ if (*devgroup != -1)
+ duparg("devgroup", *argv);
+ if (get_integer(devgroup, *argv, 0))
+ invarg("Invalid \"devgroup\" value\n", *argv);
+ argc--; argv++;
+ continue;
}
if (matches(*argv, "help") == 0)
usage();
@@ -405,6 +421,11 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
argc--; argv++;
}
+ if (*dev && (*devgroup != -1)) {
+ fprintf(stderr, "dev and devgroup cannot be both be present.\n");
+ exit(-1);
+ }
+
return ret - argc;
}
@@ -415,6 +436,7 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv)
char *name = NULL;
char *link = NULL;
char *type = NULL;
+ int devgroup;
struct link_util *lu = NULL;
struct iplink_req req;
int ret;
@@ -426,12 +448,31 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv)
req.n.nlmsg_type = cmd;
req.i.ifi_family = preferred_family;
- ret = iplink_parse(argc, argv, &req, &name, &type, &link, &dev);
+ ret = iplink_parse(argc, argv, &req, &name, &type, &link, &dev, &devgroup);
if (ret < 0)
return ret;
argc -= ret;
argv += ret;
+
+ if (devgroup != -1) {
+ if (argc) {
+ fprintf(stderr, "Garbage instead of arguments \"%s ...\". "
+ "Try \"ip link help\".\n", *argv);
+ return -1;
+ }
+ if (flags & NLM_F_CREATE) {
+ fprintf(stderr, "devgroup cannot be used when "
+ "creating devices.\n");
+ return -1;
+ }
+
+ addattr32(&req.n, sizeof(req), IFLA_FILTERGROUP, devgroup);
+ if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
+ exit(2);
+ return 0;
+ }
+
ll_init_map(&rth);
if (type) {
@@ -30,6 +30,7 @@ static int veth_parse_opt(struct link_util *lu, int argc, char **argv,
char *name, *type, *link, *dev;
int err, len;
struct rtattr * data;
+ int devgroup;
if (strcmp(argv[0], "peer") != 0) {
usage();
@@ -42,7 +43,7 @@ static int veth_parse_opt(struct link_util *lu, int argc, char **argv,
hdr->nlmsg_len += sizeof(struct ifinfomsg);
err = iplink_parse(argc - 1, argv + 1, (struct iplink_req *)hdr,
- &name, &type, &link, &dev);
+ &name, &type, &link, &dev, &devgroup);
if (err < 0)
return err;
Users can now modify basic device parameters with a single call. We use the devgroup keyword to specify the device group to work on. For instance, to take down all interfaces in group 1: ip link set down devgroup 1 This also allows merging device groups; the command below will move all interfaces in group 1 to the default group (0). ip link set group 0 devgroup 1 Signed-off-by: Vlad Dogaru <ddvlad@rosedu.org> --- include/linux/if_link.h | 1 + include/utils.h | 3 ++- ip/iplink.c | 45 +++++++++++++++++++++++++++++++++++++++++++-- ip/link_veth.c | 3 ++- 4 files changed, 48 insertions(+), 4 deletions(-)