* [PATCH v4 1/2] iproute2: support listing devices by group
2011-02-02 18:23 [PATCH v4 0/2] iproute2: support for device groups Vlad Dogaru
@ 2011-02-02 18:23 ` Vlad Dogaru
2011-02-25 20:43 ` Stephen Hemminger
2011-02-02 18:23 ` [PATCH v4 2/2] iproute2: support device group semantics Vlad Dogaru
2011-02-02 23:01 ` [PATCH v4 0/2] iproute2: support for device groups Patrick McHardy
2 siblings, 1 reply; 8+ messages in thread
From: Vlad Dogaru @ 2011-02-02 18:23 UTC (permalink / raw)
To: netdev; +Cc: Vlad Dogaru, Stephen Hemminger, Patrick McHardy
User can specify device group to list by using the group keyword:
ip link show group test
If no group is specified, 0 (default) is implied.
Signed-off-by: Vlad Dogaru <ddvlad@rosedu.org>
---
etc/iproute2/group | 2 +
include/linux/if_link.h | 1 +
include/linux/netdevice.h | 2 +-
include/rt_names.h | 1 +
ip/ipaddress.c | 14 ++++++++++++
ip/iplink.c | 2 +-
lib/rt_names.c | 50 +++++++++++++++++++++++++++++++++++++++++++++
man/man8/ip.8 | 11 ++++++++-
8 files changed, 79 insertions(+), 4 deletions(-)
create mode 100644 etc/iproute2/group
diff --git a/etc/iproute2/group b/etc/iproute2/group
new file mode 100644
index 0000000..6f000b2
--- /dev/null
+++ b/etc/iproute2/group
@@ -0,0 +1,2 @@
+# device group names
+0 default
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index e87456c..54d05f9 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -135,6 +135,7 @@ enum {
IFLA_VF_PORTS,
IFLA_PORT_SELF,
IFLA_AF_SPEC,
+ IFLA_GROUP,
__IFLA_MAX
};
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index bec4e23..ad2e34d 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -33,7 +33,7 @@
#define MAX_ADDR_LEN 32 /* Largest hardware address length */
-
+#define INIT_NETDEV_GROUP 0 /* Initial group net devices belong to */
/* Media selection options. */
enum {
diff --git a/include/rt_names.h b/include/rt_names.h
index 07a10e0..e5dbd45 100644
--- a/include/rt_names.h
+++ b/include/rt_names.h
@@ -13,6 +13,7 @@ int rtnl_rtscope_a2n(__u32 *id, char *arg);
int rtnl_rttable_a2n(__u32 *id, char *arg);
int rtnl_rtrealm_a2n(__u32 *id, char *arg);
int rtnl_dsfield_a2n(__u32 *id, char *arg);
+int rtnl_group_a2n(int *id, char *arg);
const char *inet_proto_n2a(int proto, char *buf, int len);
int inet_proto_a2n(char *buf);
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index a775ecd..e4748e3 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -49,6 +49,7 @@ static struct
char *flushb;
int flushp;
int flushe;
+ int group;
} filter;
static int do_link;
@@ -246,6 +247,12 @@ int print_linkinfo(const struct sockaddr_nl *who,
fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0))
return 0;
+ if (tb[IFLA_GROUP]) {
+ int group = *(int*)RTA_DATA(tb[IFLA_GROUP]);
+ if (group != filter.group)
+ return -1;
+ }
+
if (n->nlmsg_type == RTM_DELLINK)
fprintf(fp, "Deleted ");
@@ -718,9 +725,12 @@ static int ipaddr_list_or_flush(int argc, char **argv, int flush)
if (filter.family == AF_UNSPEC)
filter.family = preferred_family;
+ filter.group = INIT_NETDEV_GROUP;
+
if (flush) {
if (argc <= 0) {
fprintf(stderr, "Flush requires arguments.\n");
+
return -1;
}
if (filter.family == AF_PACKET) {
@@ -779,6 +789,10 @@ static int ipaddr_list_or_flush(int argc, char **argv, int flush)
} else if (strcmp(*argv, "label") == 0) {
NEXT_ARG();
filter.label = *argv;
+ } else if (strcmp(*argv, "group") == 0) {
+ NEXT_ARG();
+ if (rtnl_group_a2n(&filter.group, *argv))
+ invarg("Invalid \"group\" value\n", *argv);
} else {
if (strcmp(*argv, "dev") == 0) {
NEXT_ARG();
diff --git a/ip/iplink.c b/ip/iplink.c
index cb2c4f5..97a960b 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -71,7 +71,7 @@ void iplink_usage(void)
fprintf(stderr, " [ vf NUM [ mac LLADDR ]\n");
fprintf(stderr, " [ vlan VLANID [ qos VLAN-QOS ] ]\n");
fprintf(stderr, " [ rate TXRATE ] ] \n");
- fprintf(stderr, " ip link show [ DEVICE ]\n");
+ fprintf(stderr, " ip link show [ DEVICE | group GROUP ]\n");
if (iplink_have_newlink()) {
fprintf(stderr, "\n");
diff --git a/lib/rt_names.c b/lib/rt_names.c
index 52edfe3..30d43cd 100644
--- a/lib/rt_names.c
+++ b/lib/rt_names.c
@@ -447,3 +447,53 @@ int rtnl_dsfield_a2n(__u32 *id, char *arg)
return 0;
}
+
+static struct rtnl_hash_entry dflt_group_entry = { .id = 0, .name = "default" };
+
+static struct rtnl_hash_entry * rtnl_group_hash[256] = {
+ [0] = &dflt_group_entry,
+};
+
+static int rtnl_group_init;
+
+static void rtnl_group_initialize(void)
+{
+ rtnl_group_init = 1;
+ rtnl_hash_initialize("/etc/iproute2/group",
+ rtnl_group_hash, 256);
+}
+
+int rtnl_group_a2n(int *id, char *arg)
+{
+ static char *cache = NULL;
+ static unsigned long res;
+ struct rtnl_hash_entry *entry;
+ char *end;
+ int i;
+
+ if (cache && strcmp(cache, arg) == 0) {
+ *id = res;
+ return 0;
+ }
+
+ if (!rtnl_group_init)
+ rtnl_group_initialize();
+
+ for (i=0; i<256; i++) {
+ entry = rtnl_group_hash[i];
+ while (entry && strcmp(entry->name, arg))
+ entry = entry->next;
+ if (entry) {
+ cache = entry->name;
+ res = entry->id;
+ *id = res;
+ return 0;
+ }
+ }
+
+ i = strtol(arg, &end, 0);
+ if (!end || end == arg || *end || i < 0)
+ return -1;
+ *id = i;
+ return 0;
+}
diff --git a/man/man8/ip.8 b/man/man8/ip.8
index 8d55fa9..730788a 100644
--- a/man/man8/ip.8
+++ b/man/man8/ip.8
@@ -99,7 +99,9 @@ ip \- show / manipulate routing, devices, policy routing and tunnels
.ti -8
.B ip link show
-.RI "[ " DEVICE " ]"
+.RI "[ " DEVICE " | "
+.B group
+.IR GROUP " ]"
.ti -8
.BR "ip addr" " { " add " | " del " } "
@@ -1056,7 +1058,12 @@ call.
.BI dev " NAME " (default)
.I NAME
specifies the network device to show.
-If this argument is omitted all devices are listed.
+If this argument is omitted all devices in the default group are listed.
+
+.TP
+.BI group " GROUP "
+.I GROUP
+specifies what group of devices to show.
.TP
.B up
--
1.7.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v4 2/2] iproute2: support device group semantics
2011-02-02 18:23 [PATCH v4 0/2] iproute2: support for device groups Vlad Dogaru
2011-02-02 18:23 ` [PATCH v4 1/2] iproute2: support listing devices by group Vlad Dogaru
@ 2011-02-02 18:23 ` Vlad Dogaru
2011-02-02 23:01 ` [PATCH v4 0/2] iproute2: support for device groups Patrick McHardy
2 siblings, 0 replies; 8+ messages in thread
From: Vlad Dogaru @ 2011-02-02 18:23 UTC (permalink / raw)
To: netdev; +Cc: Vlad Dogaru, Stephen Hemminger, Patrick McHardy
Add the group keyword to ip link set, which has the following meaning:
If both a group and a device name are pressent, we change the device's
group to the specified one. If only a group is present, then the
operation specified by the rest of the command should apply on an entire
group, not a single device.
So, to set eth0 to the default group, one would use
ip link set dev eth0 group default
Conversely, to set all the devices in the default group down, use
ip link set group default down
Signed-off-by: Vlad Dogaru <ddvlad@rosedu.org>
---
include/utils.h | 3 ++-
ip/iplink.c | 40 +++++++++++++++++++++++++++++++++++++---
ip/link_veth.c | 3 ++-
man/man8/ip.8 | 19 +++++++++++++++++--
4 files changed, 58 insertions(+), 7 deletions(-)
diff --git a/include/utils.h b/include/utils.h
index 3da6998..595a7d6 100644
--- a/include/utils.h
+++ b/include/utils.h
@@ -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 *group);
#endif /* __UTILS_H__ */
diff --git a/ip/iplink.c b/ip/iplink.c
index 97a960b..8160855 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -51,7 +51,7 @@ void iplink_usage(void)
fprintf(stderr, " type TYPE [ ARGS ]\n");
fprintf(stderr, " ip link delete DEV type TYPE [ ARGS ]\n");
fprintf(stderr, "\n");
- fprintf(stderr, " ip link set DEVICE [ { up | down } ]\n");
+ fprintf(stderr, " ip link set { dev DEVICE | group DEVGROUP } [ { up | down } ]\n");
} else
fprintf(stderr, "Usage: ip link set DEVICE [ { up | down } ]\n");
@@ -244,7 +244,7 @@ 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 *group)
{
int ret, len;
char abuf[32];
@@ -253,6 +253,7 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
int netns = -1;
int vf = -1;
+ *group = -1;
ret = argc;
while (argc > 0) {
@@ -383,6 +384,12 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req,
*argv, strlen(*argv));
argc--; argv++;
break;
+ } else if (strcmp(*argv, "group") == 0) {
+ NEXT_ARG();
+ if (*group != -1)
+ duparg("group", *argv);
+ if (rtnl_group_a2n(group, *argv))
+ invarg("Invalid \"group\" value\n", *argv);
} else {
if (strcmp(*argv, "dev") == 0) {
NEXT_ARG();
@@ -406,6 +413,7 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv)
char *name = NULL;
char *link = NULL;
char *type = NULL;
+ int group;
struct link_util *lu = NULL;
struct iplink_req req;
int ret;
@@ -417,12 +425,38 @@ 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, &group);
if (ret < 0)
return ret;
argc -= ret;
argv += ret;
+
+ if (group != -1) {
+ if (dev)
+ addattr_l(&req.n, sizeof(req), IFLA_GROUP,
+ &group, sizeof(group));
+ else {
+ if (argc) {
+ fprintf(stderr, "Garbage instead of arguments "
+ "\"%s ...\". Try \"ip link "
+ "help\".\n", *argv);
+ return -1;
+ }
+ if (flags & NLM_F_CREATE) {
+ fprintf(stderr, "group cannot be used when "
+ "creating devices.\n");
+ return -1;
+ }
+
+ req.i.ifi_index = 0;
+ addattr32(&req.n, sizeof(req), IFLA_GROUP, group);
+ if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
+ exit(2);
+ return 0;
+ }
+ }
+
ll_init_map(&rth);
if (type) {
diff --git a/ip/link_veth.c b/ip/link_veth.c
index 9f5e871..3d19b01 100644
--- a/ip/link_veth.c
+++ b/ip/link_veth.c
@@ -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 group;
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, &group);
if (err < 0)
return err;
diff --git a/man/man8/ip.8 b/man/man8/ip.8
index 730788a..8f82842 100644
--- a/man/man8/ip.8
+++ b/man/man8/ip.8
@@ -55,8 +55,10 @@ ip \- show / manipulate routing, devices, policy routing and tunnels
.RI "[ " ARGS " ]"
.ti -8
-.BI "ip link set " DEVICE
-.RB "{ " up " | " down " | " arp " { " on " | " off " } |"
+.BR "ip link set " {
+.IR DEVICE " | "
+.BI "group " GROUP
+.RB "} { " up " | " down " | " arp " { " on " | " off " } |"
.br
.BR promisc " { " on " | " off " } |"
.br
@@ -930,6 +932,13 @@ specifies network device to operate on. When configuring SR-IOV Virtual Fuction
device.
.TP
+.BI group " GROUP "
+.I GROUP
+has a dual role: If both group and dev are present, then move the device to the
+specified group. If only a group is specified, then the command operates on
+all devices in that group.
+
+.TP
.BR up " and " down
change the state of the device to
.B UP
@@ -996,6 +1005,12 @@ move the device to the network namespace associated with the process
give the device a symbolic name for easy reference.
.TP
+.BI group " GROUP"
+specify the group the device belongs to.
+The available groups are listed in file
+.BR "/etc/iproute2/group" .
+
+.TP
.BI vf " NUM"
specify a Virtual Function device to be configured. The associated PF device
must be specified using the
--
1.7.1
^ permalink raw reply related [flat|nested] 8+ messages in thread