From 4a79c7a2dcefc1fc16b27303a88622b5539751cb Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 2 Dec 2013 23:42:58 -0800 Subject: [PATCH 01/16] Update headers to 3.13-rc2 --- include/linux/genetlink.h | 1 + include/linux/if_link.h | 4 +++- include/linux/netlink_diag.h | 1 + include/linux/packet_diag.h | 1 + include/linux/unix_diag.h | 1 + 5 files changed, 7 insertions(+), 1 deletion(-) diff --git a/include/linux/genetlink.h b/include/linux/genetlink.h index d48123a1..8a1d5006 100644 --- a/include/linux/genetlink.h +++ b/include/linux/genetlink.h @@ -28,6 +28,7 @@ struct genlmsghdr { #define GENL_ID_GENERATE 0 #define GENL_ID_CTRL NLMSG_MIN_TYPE #define GENL_ID_VFS_DQUOT (NLMSG_MIN_TYPE + 1) +#define GENL_ID_PMCRAID (NLMSG_MIN_TYPE + 2) /************************************************************************** * Controller diff --git a/include/linux/if_link.h b/include/linux/if_link.h index 93654e7a..4b727a55 100644 --- a/include/linux/if_link.h +++ b/include/linux/if_link.h @@ -486,7 +486,9 @@ enum { IFLA_HSR_UNSPEC, IFLA_HSR_SLAVE1, IFLA_HSR_SLAVE2, - IFLA_HSR_MULTICAST_SPEC, + IFLA_HSR_MULTICAST_SPEC, /* Last byte of supervision addr */ + IFLA_HSR_SUPERVISION_ADDR, /* Supervision frame multicast addr */ + IFLA_HSR_SEQ_NR, __IFLA_HSR_MAX, }; diff --git a/include/linux/netlink_diag.h b/include/linux/netlink_diag.h index 4e31db4e..f2159d30 100644 --- a/include/linux/netlink_diag.h +++ b/include/linux/netlink_diag.h @@ -33,6 +33,7 @@ struct netlink_diag_ring { }; enum { + /* NETLINK_DIAG_NONE, standard nl API requires this attribute! */ NETLINK_DIAG_MEMINFO, NETLINK_DIAG_GROUPS, NETLINK_DIAG_RX_RING, diff --git a/include/linux/packet_diag.h b/include/linux/packet_diag.h index b2cc0cd9..d08c63f3 100644 --- a/include/linux/packet_diag.h +++ b/include/linux/packet_diag.h @@ -29,6 +29,7 @@ struct packet_diag_msg { }; enum { + /* PACKET_DIAG_NONE, standard nl API requires this attribute! */ PACKET_DIAG_INFO, PACKET_DIAG_MCLIST, PACKET_DIAG_RX_RING, diff --git a/include/linux/unix_diag.h b/include/linux/unix_diag.h index b9e2a6a7..1eb0b8dd 100644 --- a/include/linux/unix_diag.h +++ b/include/linux/unix_diag.h @@ -31,6 +31,7 @@ struct unix_diag_msg { }; enum { + /* UNIX_DIAG_NONE, standard nl API requires this attribute! */ UNIX_DIAG_NAME, UNIX_DIAG_VFS, UNIX_DIAG_PEER, From 8cecdc283743ab2d25888f8dd39bd853e9e58a6c Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 21 Nov 2013 22:37:17 -0800 Subject: [PATCH 02/16] tc: more user friendly rates Display more user friendly rates. 10Mbit is more readable than 10000Kbit Before : class htb 1:2 root prio 0 rate 10000Kbit ceil 10000Kbit ... After: class htb 1:2 root prio 0 rate 10Mbit ceil 10Mbit ... Signed-off-by: Eric Dumazet --- tc/tc_util.c | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/tc/tc_util.c b/tc/tc_util.c index be3ed071..67f69486 100644 --- a/tc/tc_util.c +++ b/tc/tc_util.c @@ -173,28 +173,22 @@ int get_rate(unsigned *rate, const char *str) void print_rate(char *buf, int len, __u64 rate) { - double tmp = (double)rate*8; extern int use_iec; + unsigned long kilo = use_iec ? 1024 : 1000; + const char *str = use_iec ? "i" : ""; + int i = 0; + static char *units[5] = {"", "K", "M", "G", "T"}; - if (use_iec) { - if (tmp >= 1000.0*1024.0*1024.0*1024.0) - snprintf(buf, len, "%.0fGibit", tmp/(1024.0*1024.0*1024.0)); - else if (tmp >= 1000.0*1024.0*1024.0) - snprintf(buf, len, "%.0fMibit", tmp/(1024.0*1024.0)); - else if (tmp >= 1000.0*1024) - snprintf(buf, len, "%.0fKibit", tmp/1024); - else - snprintf(buf, len, "%.0fbit", tmp); - } else { - if (tmp >= 1000.0*1000000000.0) - snprintf(buf, len, "%.0fGbit", tmp/1000000000.0); - else if (tmp >= 1000.0*1000000.0) - snprintf(buf, len, "%.0fMbit", tmp/1000000.0); - else if (tmp >= 1000.0 * 1000.0) - snprintf(buf, len, "%.0fKbit", tmp/1000.0); - else - snprintf(buf, len, "%.0fbit", tmp); + rate <<= 3; /* bytes/sec -> bits/sec */ + + for (i = 0; i < ARRAY_SIZE(units); i++) { + if (rate < kilo) + break; + if (((rate % kilo) != 0) && rate < 1000*kilo) + break; + rate /= kilo; } + snprintf(buf, len, "%.0f%s%sbit", (double)rate, units[i], str); } char * sprint_rate(__u64 rate, char *buf) From 4d98ab00de90bac916f526c83c68012d7159f712 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 6 Dec 2013 15:05:07 -0800 Subject: [PATCH 03/16] Fix FSF address in file headers --- examples/cbq.init-v0.7.3 | 3 +-- ip/ip6tunnel.c | 3 +-- ip/ipaddrlabel.c | 3 +-- ip/ipntable.c | 3 +-- ip/ipprefix.c | 3 +-- ip/ipxfrm.c | 3 +-- ip/tunnel.c | 3 +-- ip/tunnel.h | 3 +-- ip/xfrm.h | 3 +-- ip/xfrm_monitor.c | 3 +-- ip/xfrm_policy.c | 3 +-- ip/xfrm_state.c | 3 +-- tc/m_skbedit.c | 5 ++--- tc/q_multiq.c | 5 ++--- 14 files changed, 16 insertions(+), 30 deletions(-) diff --git a/examples/cbq.init-v0.7.3 b/examples/cbq.init-v0.7.3 index 888aba43..35a0a05e 100644 --- a/examples/cbq.init-v0.7.3 +++ b/examples/cbq.init-v0.7.3 @@ -18,8 +18,7 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# along with this program; if not, see . # # To get the latest version, check on Freshmeat for actual location: # diff --git a/ip/ip6tunnel.c b/ip/ip6tunnel.c index 463be42b..25d5ba32 100644 --- a/ip/ip6tunnel.c +++ b/ip/ip6tunnel.c @@ -12,8 +12,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * along with this program; if not, see . */ /* * Author: diff --git a/ip/ipaddrlabel.c b/ip/ipaddrlabel.c index 68a94ddf..8295727f 100644 --- a/ip/ipaddrlabel.c +++ b/ip/ipaddrlabel.c @@ -14,8 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * along with this program; if not, see . * * * Based on iprule.c. diff --git a/ip/ipntable.c b/ip/ipntable.c index 193e50cf..00b3b0b7 100644 --- a/ip/ipntable.c +++ b/ip/ipntable.c @@ -12,8 +12,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * along with this program; if not, see . */ /* * based on ipneigh.c diff --git a/ip/ipprefix.c b/ip/ipprefix.c index 97250778..018913e8 100644 --- a/ip/ipprefix.c +++ b/ip/ipprefix.c @@ -12,8 +12,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * along with this program; if not, see . */ /* * based on ip.c, iproute.c diff --git a/ip/ipxfrm.c b/ip/ipxfrm.c index 411d9d53..2ebfd38e 100644 --- a/ip/ipxfrm.c +++ b/ip/ipxfrm.c @@ -14,8 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * along with this program; if not, see . */ /* * based on ip.c, iproute.c diff --git a/ip/tunnel.c b/ip/tunnel.c index a6a28466..2f1ec302 100644 --- a/ip/tunnel.c +++ b/ip/tunnel.c @@ -12,8 +12,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * along with this program; if not, see . */ /* * split from ip_tunnel.c diff --git a/ip/tunnel.h b/ip/tunnel.h index 7e7fe135..9c2f5d29 100644 --- a/ip/tunnel.h +++ b/ip/tunnel.h @@ -12,8 +12,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * along with this program; if not, see . */ /* * Author: diff --git a/ip/xfrm.h b/ip/xfrm.h index 784a2012..773c92e9 100644 --- a/ip/xfrm.h +++ b/ip/xfrm.h @@ -14,8 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * along with this program; if not, see . */ /* * Authors: diff --git a/ip/xfrm_monitor.c b/ip/xfrm_monitor.c index a1f5d53d..dea0afc6 100644 --- a/ip/xfrm_monitor.c +++ b/ip/xfrm_monitor.c @@ -14,8 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * along with this program; if not, see . */ /* * based on ipmonitor.c diff --git a/ip/xfrm_policy.c b/ip/xfrm_policy.c index a8d8b98b..9421ba97 100644 --- a/ip/xfrm_policy.c +++ b/ip/xfrm_policy.c @@ -14,8 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * along with this program; if not, see . */ /* * based on iproute.c diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c index c4d2bf67..14f2fa76 100644 --- a/ip/xfrm_state.c +++ b/ip/xfrm_state.c @@ -14,8 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * along with this program; if not, see . */ /* * based on iproute.c diff --git a/tc/m_skbedit.c b/tc/m_skbedit.c index c7eef44f..cca05ed1 100644 --- a/tc/m_skbedit.c +++ b/tc/m_skbedit.c @@ -12,9 +12,8 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . * * Authors: Alexander Duyck * diff --git a/tc/q_multiq.c b/tc/q_multiq.c index 546ae011..de292027 100644 --- a/tc/q_multiq.c +++ b/tc/q_multiq.c @@ -12,9 +12,8 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . * * Author: Alexander Duyck * From d2468da0a317c87ded0a9a0ae6d7d8bc7ab2e4d2 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 20 Dec 2013 08:15:02 -0800 Subject: [PATCH 04/16] check return value of rtnl_send and related functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use warn_unused_result to enforce checking return value of rtnl_send, and fix where the errors are. Suggested by initial patch from Petr Písař --- include/libnetlink.h | 28 ++++++++++++++++++++-------- ip/iplink.c | 5 ++++- ip/ipnetconf.c | 5 ++++- misc/arpd.c | 6 +++++- misc/ss.c | 4 +++- 5 files changed, 36 insertions(+), 12 deletions(-) diff --git a/include/libnetlink.h b/include/libnetlink.h index ec3d6576..fe7d5d38 100644 --- a/include/libnetlink.h +++ b/include/libnetlink.h @@ -22,13 +22,22 @@ struct rtnl_handle extern int rcvbuf; -extern int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions); -extern int rtnl_open_byproto(struct rtnl_handle *rth, unsigned subscriptions, int protocol); +extern int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions) + __attribute__((warn_unused_result)); + +extern int rtnl_open_byproto(struct rtnl_handle *rth, unsigned subscriptions, + int protocol) + __attribute__((warn_unused_result)); + extern void rtnl_close(struct rtnl_handle *rth); -extern int rtnl_wilddump_request(struct rtnl_handle *rth, int fam, int type); +extern int rtnl_wilddump_request(struct rtnl_handle *rth, int fam, int type) + __attribute__((warn_unused_result)); extern int rtnl_wilddump_req_filter(struct rtnl_handle *rth, int fam, int type, - __u32 filt_mask); -extern int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len); + __u32 filt_mask) + __attribute__((warn_unused_result)); +extern int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, + int len) + __attribute__((warn_unused_result)); typedef int (*rtnl_filter_t)(const struct sockaddr_nl *, struct nlmsghdr *n, void *); @@ -44,9 +53,12 @@ extern int rtnl_dump_filter_l(struct rtnl_handle *rth, extern int rtnl_dump_filter(struct rtnl_handle *rth, rtnl_filter_t filter, void *arg); extern int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, - unsigned groups, struct nlmsghdr *answer); -extern int rtnl_send(struct rtnl_handle *rth, const void *buf, int); -extern int rtnl_send_check(struct rtnl_handle *rth, const void *buf, int); + unsigned groups, struct nlmsghdr *answer) + __attribute__((warn_unused_result)); +extern int rtnl_send(struct rtnl_handle *rth, const void *buf, int) + __attribute__((warn_unused_result)); +extern int rtnl_send_check(struct rtnl_handle *rth, const void *buf, int) + __attribute__((warn_unused_result)); extern int addattr(struct nlmsghdr *n, int maxlen, int type); extern int addattr8(struct nlmsghdr *n, int maxlen, int type, __u8 data); diff --git a/ip/iplink.c b/ip/iplink.c index 58b6c203..e0c14e62 100644 --- a/ip/iplink.c +++ b/ip/iplink.c @@ -178,7 +178,10 @@ static int iplink_have_newlink(void) req.n.nlmsg_type = RTM_NEWLINK; req.i.ifi_family = AF_UNSPEC; - rtnl_send(&rth, &req.n, req.n.nlmsg_len); + if (rtnl_send(&rth, &req.n, req.n.nlmsg_len) < 0) { + perror("request send failed"); + exit(1); + } rtnl_listen(&rth, accept_msg, NULL); } return have_rtnl_newlink; diff --git a/ip/ipnetconf.c b/ip/ipnetconf.c index 9a77ecbf..37aaf450 100644 --- a/ip/ipnetconf.c +++ b/ip/ipnetconf.c @@ -161,7 +161,10 @@ static int do_show(int argc, char **argv) addattr_l(&req.n, sizeof(req), NETCONFA_IFINDEX, &filter.ifindex, sizeof(filter.ifindex)); - rtnl_send(&rth, &req.n, req.n.nlmsg_len); + if (rtnl_send(&rth, &req.n, req.n.nlmsg_len) < 0) { + perror("Can not send request"); + exit(1); + } rtnl_listen(&rth, print_netconf, stdout); } else { dump: diff --git a/misc/arpd.c b/misc/arpd.c index ec9d570f..bfe7de94 100644 --- a/misc/arpd.c +++ b/misc/arpd.c @@ -428,7 +428,11 @@ static int do_one_request(struct nlmsghdr *n) static void load_initial_table(void) { - rtnl_wilddump_request(&rth, AF_INET, RTM_GETNEIGH); + if (rtnl_wilddump_request(&rth, AF_INET, RTM_GETNEIGH) < 0) { + perror("dump request failed"); + exit(1); + } + } static void get_kern_msg(void) diff --git a/misc/ss.c b/misc/ss.c index 6f38ae7e..e59ca5c7 100644 --- a/misc/ss.c +++ b/misc/ss.c @@ -996,7 +996,9 @@ static int xll_initted = 0; static void xll_init(void) { struct rtnl_handle rth; - rtnl_open(&rth, 0); + if (rtnl_open(&rth, 0) < 0) + exit(1); + ll_init_map(&rth); rtnl_close(&rth); xll_initted = 1; From be2c3142f9a76ae1f036fc4316ff425f6455ce3a Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 20 Dec 2013 08:25:13 -0800 Subject: [PATCH 05/16] veth: fix uninitialized arguments Based on patch by Sergey Popovich This fixes crash when ip-link(8) invoced with command: ip link add dev veth1a type veth peer --- ip/link_veth.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ip/link_veth.c b/ip/link_veth.c index 7730f394..f357182f 100644 --- a/ip/link_veth.c +++ b/ip/link_veth.c @@ -26,7 +26,10 @@ static void usage(void) static int veth_parse_opt(struct link_util *lu, int argc, char **argv, struct nlmsghdr *hdr) { - char *name, *type, *link, *dev; + char *dev = NULL; + char *name = NULL; + char *link = NULL; + char *type = NULL; int err, len; struct rtattr * data; int group; From e0d47aa303d7224f9be10fd769592cca5090085f Mon Sep 17 00:00:00 2001 From: Sergey Popovich Date: Wed, 11 Dec 2013 14:25:07 +0200 Subject: [PATCH 06/16] Handle netdev group for veth peer too Currently ip-link(8) parses, but ignores "group" argument to peer interface on veth creation. Insert IFLA_GROUP attribute for peer interface when present. Signed-off-by: Sergey Popovich --- ip/link_veth.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ip/link_veth.c b/ip/link_veth.c index f357182f..62cb5a55 100644 --- a/ip/link_veth.c +++ b/ip/link_veth.c @@ -56,6 +56,9 @@ static int veth_parse_opt(struct link_util *lu, int argc, char **argv, addattr_l(hdr, 1024, IFLA_IFNAME, name, len); } + if (group != -1) + addattr32(hdr, 1024, IFLA_GROUP, group); + data->rta_len = (void *)NLMSG_TAIL(hdr) - (void *)data; return argc - 1 - err; } From 5c0aec93a51694474a3a743a6a0a3840e9b1233b Mon Sep 17 00:00:00 2001 From: Arvid Brodin Date: Tue, 17 Dec 2013 02:22:46 +0100 Subject: [PATCH 07/16] ip: Add HSR support Add basic support for High-Availability Seamless Redundancy (HSR) network devices. Signed-off-by: Arvid Brodin --- ip/Makefile | 2 +- ip/iplink_hsr.c | 129 ++++++++++++++++++++++++++++++++++++++++++ man/man8/ip-link.8.in | 1 + 3 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 ip/iplink_hsr.c diff --git a/ip/Makefile b/ip/Makefile index 89a7a36a..6b08cb57 100644 --- a/ip/Makefile +++ b/ip/Makefile @@ -5,7 +5,7 @@ IPOBJ=ip.o ipaddress.o ipaddrlabel.o iproute.o iprule.o ipnetns.o \ iplink_vlan.o link_veth.o link_gre.o iplink_can.o \ iplink_macvlan.o iplink_macvtap.o ipl2tp.o link_vti.o \ iplink_vxlan.o tcp_metrics.o iplink_ipoib.o ipnetconf.o link_ip6tnl.o \ - link_iptnl.o link_gre6.o iplink_bond.o + link_iptnl.o link_gre6.o iplink_bond.o iplink_hsr.o RTMONOBJ=rtmon.o diff --git a/ip/iplink_hsr.c b/ip/iplink_hsr.c new file mode 100644 index 00000000..136da358 --- /dev/null +++ b/ip/iplink_hsr.c @@ -0,0 +1,129 @@ +/* + * iplink_hsr.c HSR device support + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Authors: Arvid Brodin + * + * Based on iplink_vlan.c by Patrick McHardy + */ + +#include +#include +#include +#include /* Needed by linux/if.h for some reason */ +#include +#include +#include "rt_names.h" +#include "utils.h" +#include "ip_common.h" + +static void usage(void) +{ + fprintf(stderr, +"Usage:\tip link add name NAME type hsr slave1 SLAVE1-IF slave2 SLAVE2-IF\n" +"\t[ supervision ADDR-BYTE ]\n" +"\n" +"NAME\n" +" name of new hsr device (e.g. hsr0)\n" +"SLAVE1-IF, SLAVE2-IF\n" +" the two slave devices bound to the HSR device\n" +"ADDR-BYTE\n" +" 0-255; the last byte of the multicast address used for HSR supervision\n" +" frames (default = 0)\n"); +} + +static int hsr_parse_opt(struct link_util *lu, int argc, char **argv, + struct nlmsghdr *n) +{ + int ifindex; + unsigned char multicast_spec; + + while (argc > 0) { + if (matches(*argv, "supervision") == 0) { + NEXT_ARG(); + if (get_u8(&multicast_spec, *argv, 0)) + invarg("ADDR-BYTE is invalid", *argv); + addattr_l(n, 1024, IFLA_HSR_MULTICAST_SPEC, + &multicast_spec, 1); + } else if (matches(*argv, "slave1") == 0) { + NEXT_ARG(); + ifindex = ll_name_to_index(*argv); + if (ifindex == 0) + invarg("No such interface", *argv); + addattr_l(n, 1024, IFLA_HSR_SLAVE1, &ifindex, 4); + } else if (matches(*argv, "slave2") == 0) { + NEXT_ARG(); + ifindex = ll_name_to_index(*argv); + if (ifindex == 0) + invarg("No such interface", *argv); + addattr_l(n, 1024, IFLA_HSR_SLAVE2, &ifindex, 4); + } else if (matches(*argv, "help") == 0) { + usage(); + return -1; + } else { + fprintf(stderr, "hsr: what is \"%s\"?\n", *argv); + usage(); + return -1; + } + argc--, argv++; + } + + return 0; +} + +static void hsr_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) +{ + SPRINT_BUF(b1); + + if (!tb) + return; + + if (tb[IFLA_HSR_SLAVE1] && + RTA_PAYLOAD(tb[IFLA_HSR_SLAVE1]) < sizeof(__u32)) + return; + if (tb[IFLA_HSR_SLAVE2] && + RTA_PAYLOAD(tb[IFLA_HSR_SLAVE2]) < sizeof(__u32)) + return; + if (tb[IFLA_HSR_SEQ_NR] && + RTA_PAYLOAD(tb[IFLA_HSR_SEQ_NR]) < sizeof(__u16)) + return; + if (tb[IFLA_HSR_SUPERVISION_ADDR] && + RTA_PAYLOAD(tb[IFLA_HSR_SUPERVISION_ADDR]) < ETH_ALEN) + return; + + fprintf(f, "slave1 "); + if (tb[IFLA_HSR_SLAVE1]) + fprintf(f, "%s ", + ll_index_to_name(rta_getattr_u32(tb[IFLA_HSR_SLAVE1]))); + else + fprintf(f, " "); + + fprintf(f, "slave2 "); + if (tb[IFLA_HSR_SLAVE2]) + fprintf(f, "%s ", + ll_index_to_name(rta_getattr_u32(tb[IFLA_HSR_SLAVE2]))); + else + fprintf(f, " "); + + if (tb[IFLA_HSR_SEQ_NR]) + fprintf(f, "sequence %d ", + rta_getattr_u16(tb[IFLA_HSR_SEQ_NR])); + + if (tb[IFLA_HSR_SUPERVISION_ADDR]) + fprintf(f, "supervision %s ", + ll_addr_n2a(RTA_DATA(tb[IFLA_HSR_SUPERVISION_ADDR]), + RTA_PAYLOAD(tb[IFLA_HSR_SUPERVISION_ADDR]), + ARPHRD_VOID, + b1, sizeof(b1))); +} + +struct link_util hsr_link_util = { + .id = "hsr", + .maxattr = IFLA_VLAN_MAX, + .parse_opt = hsr_parse_opt, + .print_opt = hsr_print_opt, +}; diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in index 1825dc54..3986a5a9 100644 --- a/man/man8/ip-link.8.in +++ b/man/man8/ip-link.8.in @@ -54,6 +54,7 @@ ip-link \- network device configuration .BR bond " ]" .BR can " | " .BR dummy " | " +.BR hsr " | " .BR ifb " | " .BR ipoib " |" .BR macvlan " | " From 64b7db4db78620cd4e7c4067a4fb3aabd2252998 Mon Sep 17 00:00:00 2001 From: Jamal Hadi Salim Date: Sat, 21 Dec 2013 16:38:36 -0500 Subject: [PATCH 08/16] skbedit to default to pipe Allow skbedit to be used as is in an action chain by default without need to specify pipe Signed-off-by: Jamal Hadi Salim --- tc/m_skbedit.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tc/m_skbedit.c b/tc/m_skbedit.c index cca05ed1..6b582f30 100644 --- a/tc/m_skbedit.c +++ b/tc/m_skbedit.c @@ -99,6 +99,7 @@ parse_skbedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, argv++; } + sel.action = TC_ACT_PIPE; if (argc) { if (matches(*argv, "reclassify") == 0) { sel.action = TC_ACT_RECLASSIFY; From 02b1d345b7540328026b42a406a52f69b796dfb9 Mon Sep 17 00:00:00 2001 From: Jamal Hadi Salim Date: Sat, 21 Dec 2013 16:38:37 -0500 Subject: [PATCH 09/16] skbedit print missing metadata skbedit should print the index and other generic metadata info Signed-off-by: Jamal Hadi Salim --- tc/m_skbedit.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tc/m_skbedit.c b/tc/m_skbedit.c index 6b582f30..4b4ee060 100644 --- a/tc/m_skbedit.c +++ b/tc/m_skbedit.c @@ -165,6 +165,7 @@ static int print_skbedit(struct action_util *au, FILE *f, struct rtattr *arg) __u32 *priority; __u32 *mark; __u16 *queue_mapping; + struct tc_skbedit *p = NULL; if (arg == NULL) return -1; @@ -175,6 +176,7 @@ static int print_skbedit(struct action_util *au, FILE *f, struct rtattr *arg) fprintf(f, "[NULL skbedit parameters]"); return -1; } + p = RTA_DATA(tb[TCA_SKBEDIT_PARMS]); fprintf(f, " skbedit"); @@ -191,6 +193,8 @@ static int print_skbedit(struct action_util *au, FILE *f, struct rtattr *arg) fprintf(f, " mark %d", *mark); } + fprintf(f, "\n\t index %d ref %d bind %d", p->index, p->refcnt, p->bindcnt); + if (show_stats) { if (tb[TCA_SKBEDIT_TM]) { struct tcf_t *tm = RTA_DATA(tb[TCA_SKBEDIT_TM]); @@ -198,6 +202,8 @@ static int print_skbedit(struct action_util *au, FILE *f, struct rtattr *arg) } } + fprintf(f, "\n "); + return 0; } From 4bfb21ca2043dc5251102e4debcc0ae27f7304e7 Mon Sep 17 00:00:00 2001 From: Jamal Hadi Salim Date: Sat, 21 Dec 2013 17:16:53 -0500 Subject: [PATCH 10/16] policer - retire old syntax attached. cheers, jamal commit b82057d9ec851a8aba8a295b959190ef5098f330 Author: Jamal Hadi Salim Date: Sat Dec 21 17:00:11 2013 -0500 After a decade of trying to deprecate the old policer syntax, I believe it is time to kill it. The kernel build option for old policer is gone for at least 5 years now (although backward compatibility is still there). Being backward compatible meant hijacking the keyword "action" and was obstructing policies like: tc filter add dev eth0 parent ffff: protocol ip pref 10 \ u32 match ip protocol 1 0xff flowid 1:10 \ action skbedit mark 1 \ action police rate 10kbit burst 10k pipe \ action skbedit mark 2 \ action police rate 20kbit burst 20k pipe \ action action mirred egress mirror dev dummy0 Signed-off-by: Jamal Hadi Salim --- tc/m_police.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tc/m_police.c b/tc/m_police.c index 300287e9..df295e04 100644 --- a/tc/m_police.c +++ b/tc/m_police.c @@ -38,7 +38,6 @@ static void usage(void) fprintf(stderr, " [ peakrate BPS ] [ avrate BPS ] [ overhead BYTES ]\n"); fprintf(stderr, " [ linklayer TYPE ] [ ACTIONTERM ]\n"); - fprintf(stderr, "Old Syntax ACTIONTERM := action [/NOTEXCEEDACT] \n"); fprintf(stderr, "New Syntax ACTIONTERM := conform-exceed [/NOTEXCEEDACT] \n"); fprintf(stderr, "Where: *EXCEEDACT := pipe | ok | reclassify | drop | continue \n"); fprintf(stderr, "Where: pipe is only valid for new syntax \n"); @@ -150,6 +149,7 @@ int act_parse_police(struct action_util *a,int *argc_p, char ***argv_p, int tca_ while (argc > 0) { + fprintf(stderr,"police argc %d argv %s\n", argc, *argv); if (matches(*argv, "index") == 0) { NEXT_ARG(); if (get_u32(&p.index, *argv, 10)) { @@ -230,8 +230,7 @@ int act_parse_police(struct action_util *a,int *argc_p, char ***argv_p, int tca_ p.action = TC_POLICE_OK; } else if (matches(*argv, "pipe") == 0) { p.action = TC_POLICE_PIPE; - } else if (strcmp(*argv, "action") == 0 || - strcmp(*argv, "conform-exceed") == 0) { + } else if (strcmp(*argv, "conform-exceed") == 0) { NEXT_ARG(); if (get_police_result(&p.action, &presult, *argv)) { fprintf(stderr, "Illegal \"action\"\n"); From 352f6f97bef6baefa21d973b914a67e7feac3d8f Mon Sep 17 00:00:00 2001 From: Jamal Hadi Salim Date: Sun, 22 Dec 2013 07:50:09 -0500 Subject: [PATCH 11/16] simple print newline attached. cheers, jamal commit d7869e6167c3553e93e254940b0647032b40fed8 Author: Jamal Hadi Salim Date: Sun Dec 22 07:46:28 2013 -0500 print new line at the end for aesthetics Signed-off-by: Jamal Hadi Salim --- tc/m_simple.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tc/m_simple.c b/tc/m_simple.c index 02244406..a8e1d6b2 100644 --- a/tc/m_simple.c +++ b/tc/m_simple.c @@ -188,9 +188,9 @@ static int print_simple(struct action_util *au, FILE * f, struct rtattr *arg) if (tb[TCA_DEF_TM]) { struct tcf_t *tm = RTA_DATA(tb[TCA_DEF_TM]); print_tm(f, tm); - fprintf(f, "\n"); } } + fprintf(f, "\n"); return 0; } From b159a7f1aeb4c2fc3a9053d314bbc4d235beac67 Mon Sep 17 00:00:00 2001 From: Jamal Hadi Salim Date: Sun, 22 Dec 2013 10:33:13 -0500 Subject: [PATCH 12/16] allow batch gets of actions Attached. cheers, jamal commit c5f30cabef14c951596210b96bc9b423b0d39592 Author: Jamal Hadi Salim Date: Sun Dec 22 10:24:17 2013 -0500 Allow batching of action gets Example: ---- tc actions get \ action gact index 100 \ action gact index 4 ---- Signed-off-by: Jamal Hadi Salim --- tc/m_action.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tc/m_action.c b/tc/m_action.c index 4acabef0..51085ecb 100644 --- a/tc/m_action.c +++ b/tc/m_action.c @@ -144,6 +144,7 @@ new_cmd(char **argv) if ((matches(*argv, "change") == 0) || (matches(*argv, "replace") == 0)|| (matches(*argv, "delete") == 0)|| + (matches(*argv, "get") == 0)|| (matches(*argv, "add") == 0)) return 1; From f24a7e720592aa8f267a66b8d80f5617f4c1df61 Mon Sep 17 00:00:00 2001 From: Jamal Hadi Salim Date: Sun, 22 Dec 2013 10:37:44 -0500 Subject: [PATCH 13/16] dont skip action order attached. cheers, jamal commit 58d78f9f6447df324cdeb99262442c5e3f1f924b Author: Jamal Hadi Salim Date: Sun Dec 22 10:34:18 2013 -0500 dont skip displaying of action chains or lists by TCA_ACT_MAX_PRIO Signed-off-by: Jamal Hadi Salim --- tc/m_action.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tc/m_action.c b/tc/m_action.c index 51085ecb..77479d6e 100644 --- a/tc/m_action.c +++ b/tc/m_action.c @@ -32,7 +32,6 @@ static struct action_util * action_list; #ifdef CONFIG_GACT int gact_ld = 0 ; //fuckin backward compatibility #endif -int batch_c = 0; int tab_flush = 0; static void act_usage(void) @@ -304,7 +303,7 @@ tc_print_action(FILE * f, const struct rtattr *arg) for (i = 0; i < TCA_ACT_MAX_PRIO; i++) { if (tb[i]) { - fprintf(f, "\n\taction order %d: ", i + batch_c); + fprintf(f, "\n\taction order %d: ", i); if (0 > tc_print_one_action(f, tb[i])) { fprintf(f, "Error printing action\n"); } @@ -312,7 +311,6 @@ tc_print_action(FILE * f, const struct rtattr *arg) } - batch_c+=TCA_ACT_MAX_PRIO ; return 0; } From 5e25cf77b9e7d9ae9959db0ac5d731cfbf3b2717 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Thu, 26 Dec 2013 23:15:20 +0400 Subject: [PATCH 14/16] iproute: Make it possible to specify index on link creation The RTM_NEWLINK message accepts ifi_index non-zero value and lets creation of links with given index (if it's free, or course). This functionality is available since linux-v3.5. This patch makes this API available via ip tool. Signed-off-by: Pavel Emelyanov --- include/utils.h | 2 +- ip/iplink.c | 12 +++++++++--- ip/link_veth.c | 8 +++++++- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/include/utils.h b/include/utils.h index a3e310ee..a4b5b4cc 100644 --- a/include/utils.h +++ b/include/utils.h @@ -156,5 +156,5 @@ extern int inet_get_addr(const char *src, __u32 *dst, struct in6_addr *dst6); struct iplink_req; int iplink_parse(int argc, char **argv, struct iplink_req *req, char **name, char **type, char **link, char **dev, - int *group); + int *group, int *index); #endif /* __UTILS_H__ */ diff --git a/ip/iplink.c b/ip/iplink.c index e0c14e62..343b29f9 100644 --- a/ip/iplink.c +++ b/ip/iplink.c @@ -47,7 +47,7 @@ void iplink_usage(void) fprintf(stderr, " [ txqueuelen PACKETS ]\n"); fprintf(stderr, " [ address LLADDR ]\n"); fprintf(stderr, " [ broadcast LLADDR ]\n"); - fprintf(stderr, " [ mtu MTU ]\n"); + fprintf(stderr, " [ mtu MTU ] [index IDX ]\n"); fprintf(stderr, " [ numtxqueues QUEUE_COUNT ]\n"); fprintf(stderr, " [ numrxqueues QUEUE_COUNT ]\n"); fprintf(stderr, " type TYPE [ ARGS ]\n"); @@ -291,7 +291,7 @@ static 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, int *group) + char **name, char **type, char **link, char **dev, int *group, int *index) { int ret, len; char abuf[32]; @@ -315,6 +315,9 @@ int iplink_parse(int argc, char **argv, struct iplink_req *req, } else if (strcmp(*argv, "name") == 0) { NEXT_ARG(); *name = *argv; + } else if (strcmp(*argv, "index") == 0) { + NEXT_ARG(); + *index = atoi(*argv); } else if (matches(*argv, "link") == 0) { NEXT_ARG(); *link = *argv; @@ -506,6 +509,7 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv) char *name = NULL; char *link = NULL; char *type = NULL; + int index = 0; int group; struct link_util *lu = NULL; struct iplink_req req; @@ -518,7 +522,7 @@ 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, &group); + ret = iplink_parse(argc, argv, &req, &name, &type, &link, &dev, &group, &index); if (ret < 0) return ret; @@ -578,6 +582,8 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv) } addattr_l(&req.n, sizeof(req), IFLA_LINK, &ifindex, 4); } + + req.i.ifi_index = index; } if (name) { diff --git a/ip/link_veth.c b/ip/link_veth.c index 62cb5a55..3cbeb544 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 = NULL; char *link = NULL; char *type = NULL; + int index = 0; int err, len; struct rtattr * data; int group; @@ -45,7 +46,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, &group); + &name, &type, &link, &dev, &group, &index); if (err < 0) return err; @@ -56,6 +57,11 @@ static int veth_parse_opt(struct link_util *lu, int argc, char **argv, addattr_l(hdr, 1024, IFLA_IFNAME, name, len); } + if (index) { + struct ifinfomsg *ifi = (struct ifinfomsg *)(data + 1); + ifi->ifi_index = index; + } + if (group != -1) addattr32(hdr, 1024, IFLA_GROUP, group); From 1c28bd597bdac6948fe8321f9abf4cb943270d1b Mon Sep 17 00:00:00 2001 From: Hangbin Liu Date: Fri, 6 Dec 2013 00:19:01 +0800 Subject: [PATCH 15/16] iptunnel: Allow GRE_KEY for vti interface The vti interface will use GRE_KEY to match the right policy in kernel. So we can not return fail when the tunnel is vti. Signed-off-by: Hangbin Liu --- ip/iptunnel.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ip/iptunnel.c b/ip/iptunnel.c index 40186d3d..8479c720 100644 --- a/ip/iptunnel.c +++ b/ip/iptunnel.c @@ -240,8 +240,9 @@ static int parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p) } } - if (p->iph.protocol == IPPROTO_IPIP || p->iph.protocol == IPPROTO_IPV6) { - if ((p->i_flags & GRE_KEY) || (p->o_flags & GRE_KEY)) { + if ((p->i_flags & GRE_KEY) || (p->o_flags & GRE_KEY)) { + if (!(p->i_flags & VTI_ISVTI) && + (p->iph.protocol != IPPROTO_GRE)) { fprintf(stderr, "Keys are not allowed with ipip and sit tunnels\n"); return -1; } From 4de8d8851d4478d0611721d22205e811279a96d5 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Mon, 30 Dec 2013 13:55:17 +0400 Subject: [PATCH 16/16] iproute: Document the "ip link add index IDX" possibility Signed-off-by: Pavel Emelyanov --- man/man8/ip-link.8.in | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in index 3986a5a9..94d07fc5 100644 --- a/man/man8/ip-link.8.in +++ b/man/man8/ip-link.8.in @@ -39,6 +39,8 @@ ip-link \- network device configuration .br .RB "[ " mtu .IR MTU " ]" +.RB "[ " index +.IR IDX " ]" .br .RB "[ " numtxqueues .IR QUEUE_COUNT " ]" @@ -217,6 +219,10 @@ specifies the number of transmit queues for new device. .BI numrxqueues " QUEUE_COUNT " specifies the number of receive queues for new device. +.TP +.BI index " IDX " +specifies the desired index of the new virtual device. The link creation fails, if the index is busy. + .TP VXLAN Type Support For a link of type