iproute2: support for device groups
Subsystems (3)
v4 cover iproute2: support for device groups
This patch series adds userspace support for network device groups. There is support for setting device groups, listing only interfaces of a specific group, and setting basic device parameters for all interfaces in a group.
Changes since version 3:
* drop devgroup keyword. There is a single keyword for specifying groups now.
* store group names internally as a hash, similar to routing table names. This is more efficient for batch mode operations.
Changes since version 2:
* groups now have names. The mapping between names and numbers (which are used by the kernel) is in /etc/iproute2/group.
* the ip man page and usage display function have been updated to reflect the new functionality.
Changes since version 1:
* a single attribute is used for both setting the group of a device and manipulating an entire group.
Vlad Dogaru (2):
iproute2: support listing devices by group
iproute2: support device group semantics
etc/iproute2/group | 2 + include/linux/if_link.h | 1 + include/linux/netdevice.h | 2 +- include/rt_names.h | 1 + include/utils.h | 3 +- ip/ipaddress.c | 14 ++++++++++++ ip/iplink.c | 42 ++++++++++++++++++++++++++++++++++--- ip/link_veth.c | 3 +- lib/rt_names.c | 50 +++++++++++++++++++++++++++++++++++++++++++++ man/man8/ip.8 | 30 +++++++++++++++++++++++--- 10 files changed, 137 insertions(+), 11 deletions(-) create mode 100644 etc/iproute2/group
PATCH v4 1/2 iproute2: support listing devices by group
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.
--- 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
etc/iproute2/group new file +2 -0
@@ -0,0 +1,2 @@ +# device group names +0 default
include/linux/if_link.h +1 -0
@@ -135,6 +135,7 @@ enum {IFLA_VF_PORTS ,IFLA_PORT_SELF ,IFLA_AF_SPEC , +IFLA_GROUP , __IFLA_MAX };
include/linux/netdevice.h +1 -1
@@ -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 {
include/rt_names.h +1 -0
@@ -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);
ip/ipaddress.c +14 -0
@@ -49,6 +49,7 @@ static structchar *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 ();
ip/iplink.c +1 -1
@@ -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" );
lib/rt_names.c +50 -0
53 lines not on this page · raw message
man/man8/ip.8 +9 -2
@@ -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
Signature · 1 line
1.7.1
Re: [PATCH v4 1/2] iproute2: support listing devices by group
Quoted 7 lines · On Wed, 2 Feb 2011 20:23:40 +0200 Vlad Dogaru <[email protected]> wrote:
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 <[email protected]>
I applied this to net-next for iproute2
but INIT_NETDEV_GROUP is in a part of netdevice.h that is not exported (ie inside #ifdef KERNEL).
PATCH 1/1 netdevice: make initial group visible to userspace
Quoted 7 lines · Stephen Hemminger
Quoted 4 lines · On Wed, 2 Feb 2011 20:23:40 +0200 Vlad Dogaru <[email protected]> wrote:
User can specify device group to list by using the group keyword:
ip link show group test
Quoted 7 lines
Quoted 3 lines
If no group is specified, 0 (default) is implied.
Signed-off-by Vlad Dogaru <[email protected]>I applied this to net-next for iproute2
butINIT_NETDEV_GROUPis in a part ofnetdevice.hthat is not exported (ie inside #ifdef KERNEL).
Sorry, here is a patch for net-next that fixes the issue:
[PATCH net-next] netdevice: make initial group visible to userspace
INIT_NETDEV_GROUP is needed by userspace, move it outside __KERNEL__ guards.
--- include/linux/netdevice.h | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-)
include/linux/netdevice.h +3 -3
@@ -75,9 +75,6 @@ struct wireless_dev;#define NET_RX_SUCCESS 0/* keep 'em coming, baby */ #define NET_RX_DROP 1/* packet dropped */ -/* Initial net device group. All devices belong to group 0 by default. */ -#define INIT_NETDEV_GROUP 0 -/* * Transmit return codes: transmit return codes originate from three different * namespaces:
@@ -141,6 +138,9 @@ static inline bool dev_xmit_complete(int rc)#define MAX_ADDR_LEN 32/* Largest hardware address length */ +/* Initial net device group. All devices belong to group 0 by default. */ +#define INIT_NETDEV_GROUP 0 +#ifdef __KERNEL__/* * Compute the worst case header length according to the protocols
Signature · 1 line
1.7.1
Re: [PATCH nex-next] netdevice: make initial group visible to userspace
From: Vlad Dogaru <[email protected]>
Date: Sun, 27 Feb 2011 10:39:12 +0200
Quoted 6 lines
[PATCH net-next] netdevice: make initial group visible to userspace
INIT_NETDEV_GROUPis needed by userspace, move it outside__KERNEL__guards.Signed-off-by Vlad Dogaru <[email protected]>
Applied, thanks.
PATCH v4 2/2 iproute2: support device group semantics
In reply to Vlad DogaruAdd 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
--- 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(-)
include/utils.h +2 -1
@@ -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__ */
ip/iplink.c +37 -3
@@ -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) {
ip/link_veth.c +2 -1
@@ -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;
man/man8/ip.8 +17 -2
@@ -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
Signature · 1 line
1.7.1
Am 02.02.2011 19:23, schrieb Vlad Dogaru:
Quoted 10 lines
This patch series adds userspace support for network device groups. There is support for setting device groups, listing only interfaces of a specific group, and setting basic device parameters for all interfaces in a group.
Changes since version 3:
* drop devgroup keyword. There is a single keyword for specifying groups now.
* store group names internally as a hash, similar to routing table names. This is more efficient for batch mode operations
Looks good to me, thanks.
Quoted 6 lines · On Thu, 03 Feb 2011 00:01:38 +0100 Patrick McHardy <[email protected]> wrote:
Am 02.02.2011 19:23, schrieb Vlad Dogaru:
Quoted 5 lines
This patch series adds userspace support for network device groups. There is support for setting device groups, listing only interfaces of a specific group, and setting basic device parameters for all interfaces in a group.
Quoted 7 lines
Quoted 5 lines
Changes since version 3:
* drop devgroup keyword. There is a single keyword for specifying groups now.
* store group names internally as a hash, similar to routing table names. This is more efficient for batch mode operationsLooks good to me, thanks.
Will apply after 2.6.38 is released.