diff options
author | Stephen Hemminger <shemming@brocade.com> | 2015-12-21 21:37:21 -0800 |
---|---|---|
committer | Stephen Hemminger <shemming@brocade.com> | 2015-12-21 21:37:21 -0800 |
commit | 5d3ec4384963f7cc2f9725644c58ed7561873eee (patch) | |
tree | 1bc04da2e40519b0ae38cee6ee7d514276c4bc2a | |
parent | fd7f9c7fd11fa926bda2edc8bc492e7515753a32 (diff) | |
parent | f8fc1d101e74fc9f1f9ca57b5e494c2f7bc33bf7 (diff) | |
download | android_external_iproute2-5d3ec4384963f7cc2f9725644c58ed7561873eee.tar.gz android_external_iproute2-5d3ec4384963f7cc2f9725644c58ed7561873eee.tar.bz2 android_external_iproute2-5d3ec4384963f7cc2f9725644c58ed7561873eee.zip |
Merge branch 'master' into net-next
-rw-r--r-- | ip/ip6tunnel.c | 21 | ||||
-rw-r--r-- | ip/ipaddress.c | 9 | ||||
-rw-r--r-- | ip/iplink_vxlan.c | 19 | ||||
-rw-r--r-- | ip/iproute_lwtunnel.c | 92 | ||||
-rw-r--r-- | ip/iptunnel.c | 21 | ||||
-rw-r--r-- | ip/link_gre.c | 11 | ||||
-rw-r--r-- | ip/tunnel.c | 28 | ||||
-rw-r--r-- | ip/tunnel.h | 1 |
8 files changed, 160 insertions, 42 deletions
diff --git a/ip/ip6tunnel.c b/ip/ip6tunnel.c index 1737d88..7a3cd04 100644 --- a/ip/ip6tunnel.c +++ b/ip/ip6tunnel.c @@ -341,10 +341,6 @@ static int do_tunnels_list(struct ip6_tnl_parm2 *p) while (fgets(buf, sizeof(buf), fp) != NULL) { char name[IFNAMSIZ]; int index, type; - unsigned long rx_bytes, rx_packets, rx_errs, rx_drops, - rx_fifo, rx_frame, - tx_bytes, tx_packets, tx_errs, tx_drops, - tx_fifo, tx_colls, tx_carrier, rx_multi; struct ip6_tnl_parm2 p1; char *ptr; @@ -354,12 +350,6 @@ static int do_tunnels_list(struct ip6_tnl_parm2 *p) fprintf(stderr, "Wrong format for /proc/net/dev. Giving up.\n"); goto end; } - if (sscanf(ptr, "%lu%lu%lu%lu%lu%lu%lu%*d%lu%lu%lu%lu%lu%lu%lu", - &rx_bytes, &rx_packets, &rx_errs, &rx_drops, - &rx_fifo, &rx_frame, &rx_multi, - &tx_bytes, &tx_packets, &tx_errs, &tx_drops, - &tx_fifo, &tx_colls, &tx_carrier) != 14) - continue; if (p->name[0] && strcmp(p->name, name)) continue; index = ll_name_to_index(name); @@ -385,15 +375,8 @@ static int do_tunnels_list(struct ip6_tnl_parm2 *p) if (!ip6_tnl_parm_match(p, &p1)) continue; print_tunnel(&p1); - if (show_stats) { - printf("%s", _SL_); - printf("RX: Packets Bytes Errors CsumErrs OutOfSeq Mcasts%s", _SL_); - printf(" %-10ld %-12ld %-6ld %-8ld %-8ld %-8ld%s", - rx_packets, rx_bytes, rx_errs, rx_frame, rx_fifo, rx_multi, _SL_); - printf("TX: Packets Bytes Errors DeadLoop NoRoute NoBufs%s", _SL_); - printf(" %-10ld %-12ld %-6ld %-8ld %-8ld %-6ld", - tx_packets, tx_bytes, tx_errs, tx_colls, tx_carrier, tx_drops); - } + if (show_stats) + tnl_print_stats(ptr); printf("\n"); } err = 0; diff --git a/ip/ipaddress.c b/ip/ipaddress.c index bc8359e..a495a39 100644 --- a/ip/ipaddress.c +++ b/ip/ipaddress.c @@ -285,13 +285,20 @@ static void print_af_spec(FILE *fp, struct rtattr *af_spec_attr) parse_rtattr_nested(tb, IFLA_INET6_MAX, inet6_attr); if (tb[IFLA_INET6_ADDR_GEN_MODE]) { - switch (rta_getattr_u8(tb[IFLA_INET6_ADDR_GEN_MODE])) { + __u8 mode = rta_getattr_u8(tb[IFLA_INET6_ADDR_GEN_MODE]); + switch (mode) { case IN6_ADDR_GEN_MODE_EUI64: fprintf(fp, "addrgenmode eui64 "); break; case IN6_ADDR_GEN_MODE_NONE: fprintf(fp, "addrgenmode none "); break; + case IN6_ADDR_GEN_MODE_STABLE_PRIVACY: + fprintf(fp, "addrgenmode stable_secret "); + break; + default: + fprintf(fp, "addrgenmode %#.2hhx ", mode); + break; } } } diff --git a/ip/iplink_vxlan.c b/ip/iplink_vxlan.c index db29bf0..aa4d519 100644 --- a/ip/iplink_vxlan.c +++ b/ip/iplink_vxlan.c @@ -31,7 +31,7 @@ static void print_explain(FILE *f) fprintf(f, " [ ageing SECONDS ] [ maxaddress NUMBER ]\n"); fprintf(f, " [ [no]udpcsum ] [ [no]udp6zerocsumtx ] [ [no]udp6zerocsumrx ]\n"); fprintf(f, " [ [no]remcsumtx ] [ [no]remcsumrx ]\n"); - fprintf(f, " [ gbp ]\n"); + fprintf(f, " [ [no]external ] [ gbp ]\n"); fprintf(f, "\n"); fprintf(f, "Where: VNI := 0-16777215\n"); fprintf(f, " ADDR := { IP_ADDRESS | any }\n"); @@ -72,6 +72,7 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv, __u8 udp6zerocsumrx = 0; __u8 remcsumtx = 0; __u8 remcsumrx = 0; + __u8 metadata = 0; __u8 gbp = 0; int dst_port_set = 0; struct ifla_vxlan_port_range range = { 0, 0 }; @@ -210,6 +211,10 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv, remcsumrx = 1; } else if (!matches(*argv, "noremcsumrx")) { remcsumrx = 0; + } else if (!matches(*argv, "external")) { + metadata = 1; + } else if (!matches(*argv, "noexternal")) { + metadata = 0; } else if (!matches(*argv, "gbp")) { gbp = 1; } else if (matches(*argv, "help") == 0) { @@ -223,7 +228,12 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv, argc--, argv++; } - if (!vni_set) { + if (metadata && vni_set) { + fprintf(stderr, "vxlan: both 'external' and vni cannot be specified\n"); + return -1; + } + + if (!metadata && !vni_set) { fprintf(stderr, "vxlan: missing virtual network identifier\n"); return -1; } @@ -272,6 +282,7 @@ static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv, addattr8(n, 1024, IFLA_VXLAN_UDP_ZERO_CSUM6_RX, udp6zerocsumrx); addattr8(n, 1024, IFLA_VXLAN_REMCSUM_TX, remcsumtx); addattr8(n, 1024, IFLA_VXLAN_REMCSUM_RX, remcsumrx); + addattr8(n, 1024, IFLA_VXLAN_COLLECT_METADATA, metadata); if (noage) addattr32(n, 1024, IFLA_VXLAN_AGEING, 0); @@ -428,6 +439,10 @@ static void vxlan_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) rta_getattr_u8(tb[IFLA_VXLAN_REMCSUM_RX])) fputs("remcsumrx ", f); + if (tb[IFLA_VXLAN_COLLECT_METADATA] && + rta_getattr_u8(tb[IFLA_VXLAN_COLLECT_METADATA])) + fputs("external ", f); + if (tb[IFLA_VXLAN_GBP]) fputs("gbp ", f); } diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c index 1243977..7074906 100644 --- a/ip/iproute_lwtunnel.c +++ b/ip/iproute_lwtunnel.c @@ -115,6 +115,37 @@ static void print_encap_ila(FILE *fp, struct rtattr *encap) } } +static void print_encap_ip6(FILE *fp, struct rtattr *encap) +{ + struct rtattr *tb[LWTUNNEL_IP6_MAX+1]; + char abuf[256]; + + parse_rtattr_nested(tb, LWTUNNEL_IP6_MAX, encap); + + if (tb[LWTUNNEL_IP6_ID]) + fprintf(fp, "id %llu ", ntohll(rta_getattr_u64(tb[LWTUNNEL_IP6_ID]))); + + if (tb[LWTUNNEL_IP6_SRC]) + fprintf(fp, "src %s ", + rt_addr_n2a(AF_INET6, + RTA_PAYLOAD(tb[LWTUNNEL_IP6_SRC]), + RTA_DATA(tb[LWTUNNEL_IP6_SRC]), + abuf, sizeof(abuf))); + + if (tb[LWTUNNEL_IP6_DST]) + fprintf(fp, "dst %s ", + rt_addr_n2a(AF_INET6, + RTA_PAYLOAD(tb[LWTUNNEL_IP6_DST]), + RTA_DATA(tb[LWTUNNEL_IP6_DST]), + abuf, sizeof(abuf))); + + if (tb[LWTUNNEL_IP6_HOPLIMIT]) + fprintf(fp, "hoplimit %d ", rta_getattr_u8(tb[LWTUNNEL_IP6_HOPLIMIT])); + + if (tb[LWTUNNEL_IP6_TC]) + fprintf(fp, "tc %d ", rta_getattr_u8(tb[LWTUNNEL_IP6_TC])); +} + void lwt_print_encap(FILE *fp, struct rtattr *encap_type, struct rtattr *encap) { @@ -125,7 +156,7 @@ void lwt_print_encap(FILE *fp, struct rtattr *encap_type, et = rta_getattr_u16(encap_type); - fprintf(fp, " encap %s", format_encap_type(et)); + fprintf(fp, " encap %s ", format_encap_type(et)); switch (et) { case LWTUNNEL_ENCAP_MPLS: @@ -137,6 +168,9 @@ void lwt_print_encap(FILE *fp, struct rtattr *encap_type, case LWTUNNEL_ENCAP_ILA: print_encap_ila(fp, encap); break; + case LWTUNNEL_ENCAP_IP6: + print_encap_ip6(fp, encap); + break; } } @@ -233,6 +267,59 @@ static int parse_encap_ila(struct rtattr *rta, size_t len, return 0; } +static int parse_encap_ip6(struct rtattr *rta, size_t len, int *argcp, char ***argvp) +{ + int id_ok = 0, dst_ok = 0, tos_ok = 0, ttl_ok = 0; + char **argv = *argvp; + int argc = *argcp; + + while (argc > 0) { + if (strcmp(*argv, "id") == 0) { + __u64 id; + NEXT_ARG(); + if (id_ok++) + duparg2("id", *argv); + if (get_u64(&id, *argv, 0)) + invarg("\"id\" value is invalid\n", *argv); + rta_addattr64(rta, len, LWTUNNEL_IP6_ID, htonll(id)); + } else if (strcmp(*argv, "dst") == 0) { + inet_prefix addr; + NEXT_ARG(); + if (dst_ok++) + duparg2("dst", *argv); + get_addr(&addr, *argv, AF_INET6); + rta_addattr_l(rta, len, LWTUNNEL_IP6_DST, &addr.data, addr.bytelen); + } else if (strcmp(*argv, "tc") == 0) { + __u32 tc; + NEXT_ARG(); + if (tos_ok++) + duparg2("tc", *argv); + if (rtnl_dsfield_a2n(&tc, *argv)) + invarg("\"tc\" value is invalid\n", *argv); + rta_addattr8(rta, len, LWTUNNEL_IP6_TC, tc); + } else if (strcmp(*argv, "hoplimit") == 0) { + __u8 hoplimit; + NEXT_ARG(); + if (ttl_ok++) + duparg2("hoplimit", *argv); + if (get_u8(&hoplimit, *argv, 0)) + invarg("\"hoplimit\" value is invalid\n", *argv); + rta_addattr8(rta, len, LWTUNNEL_IP6_HOPLIMIT, hoplimit); + } else { + break; + } + argc--; argv++; + } + + /* argv is currently the first unparsed argument, + * but the lwt_parse_encap() caller will move to the next, + * so step back */ + *argcp = argc + 1; + *argvp = argv - 1; + + return 0; +} + int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp) { struct rtattr *nest; @@ -262,6 +349,9 @@ int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp) case LWTUNNEL_ENCAP_ILA: parse_encap_ila(rta, len, &argc, &argv); break; + case LWTUNNEL_ENCAP_IP6: + parse_encap_ip6(rta, len, &argc, &argv); + break; default: fprintf(stderr, "Error: unsupported encap type\n"); break; diff --git a/ip/iptunnel.c b/ip/iptunnel.c index a3ff99b..65a4e6e 100644 --- a/ip/iptunnel.c +++ b/ip/iptunnel.c @@ -405,10 +405,6 @@ static int do_tunnels_list(struct ip_tunnel_parm *p) while (fgets(buf, sizeof(buf), fp) != NULL) { char name[IFNAMSIZ]; int index, type; - unsigned long rx_bytes, rx_packets, rx_errs, rx_drops, - rx_fifo, rx_frame, - tx_bytes, tx_packets, tx_errs, tx_drops, - tx_fifo, tx_colls, tx_carrier, rx_multi; struct ip_tunnel_parm p1; char *ptr; @@ -419,12 +415,6 @@ static int do_tunnels_list(struct ip_tunnel_parm *p) fprintf(stderr, "Wrong format for /proc/net/dev. Giving up.\n"); goto end; } - if (sscanf(ptr, "%lu%lu%lu%lu%lu%lu%lu%*d%lu%lu%lu%lu%lu%lu%lu", - &rx_bytes, &rx_packets, &rx_errs, &rx_drops, - &rx_fifo, &rx_frame, &rx_multi, - &tx_bytes, &tx_packets, &tx_errs, &tx_drops, - &tx_fifo, &tx_colls, &tx_carrier) != 14) - continue; if (p->name[0] && strcmp(p->name, name)) continue; index = ll_name_to_index(name); @@ -447,15 +437,8 @@ static int do_tunnels_list(struct ip_tunnel_parm *p) (p->i_key && p1.i_key != p->i_key)) continue; print_tunnel(&p1); - if (show_stats) { - printf("%s", _SL_); - printf("RX: Packets Bytes Errors CsumErrs OutOfSeq Mcasts%s", _SL_); - printf(" %-10ld %-12ld %-6ld %-8ld %-8ld %-8ld%s", - rx_packets, rx_bytes, rx_errs, rx_frame, rx_fifo, rx_multi, _SL_); - printf("TX: Packets Bytes Errors DeadLoop NoRoute NoBufs%s", _SL_); - printf(" %-10ld %-12ld %-6ld %-8ld %-8ld %-6ld", - tx_packets, tx_bytes, tx_errs, tx_colls, tx_carrier, tx_drops); - } + if (show_stats) + tnl_print_stats(ptr); printf("\n"); } err = 0; diff --git a/ip/link_gre.c b/ip/link_gre.c index 58f416c..c85741f 100644 --- a/ip/link_gre.c +++ b/ip/link_gre.c @@ -74,6 +74,7 @@ static int gre_parse_opt(struct link_util *lu, int argc, char **argv, __u16 encapflags = 0; __u16 encapsport = 0; __u16 encapdport = 0; + __u8 metadata = 0; if (!(n->nlmsg_flags & NLM_F_CREATE)) { memset(&req, 0, sizeof(req)); @@ -148,6 +149,9 @@ get_failed: encapsport = rta_getattr_u16(greinfo[IFLA_GRE_ENCAP_SPORT]); if (greinfo[IFLA_GRE_ENCAP_DPORT]) encapdport = rta_getattr_u16(greinfo[IFLA_GRE_ENCAP_DPORT]); + + if (greinfo[IFLA_GRE_COLLECT_METADATA]) + metadata = 1; } while (argc > 0) { @@ -291,6 +295,8 @@ get_failed: encapflags |= TUNNEL_ENCAP_FLAG_REMCSUM; } else if (strcmp(*argv, "noencap-remcsum") == 0) { encapflags |= ~TUNNEL_ENCAP_FLAG_REMCSUM; + } else if (strcmp(*argv, "external") == 0) { + metadata = 1; } else usage(); argc--; argv++; @@ -325,6 +331,8 @@ get_failed: addattr16(n, 1024, IFLA_GRE_ENCAP_FLAGS, encapflags); addattr16(n, 1024, IFLA_GRE_ENCAP_SPORT, htons(encapsport)); addattr16(n, 1024, IFLA_GRE_ENCAP_DPORT, htons(encapdport)); + if (metadata) + addattr_l(n, 1024, IFLA_GRE_COLLECT_METADATA, NULL, 0); return 0; } @@ -413,6 +421,9 @@ static void gre_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]) if (oflags & GRE_CSUM) fputs("ocsum ", f); + if (tb[IFLA_GRE_COLLECT_METADATA]) + fputs("external ", f); + if (tb[IFLA_GRE_ENCAP_TYPE] && *(__u16 *)RTA_DATA(tb[IFLA_GRE_ENCAP_TYPE]) != TUNNEL_ENCAP_NONE) { __u16 type = rta_getattr_u16(tb[IFLA_GRE_ENCAP_TYPE]); diff --git a/ip/tunnel.c b/ip/tunnel.c index 79f2201..39f825b 100644 --- a/ip/tunnel.c +++ b/ip/tunnel.c @@ -195,3 +195,31 @@ __be32 tnl_parse_key(const char *name, const char *key) } return htonl(uval); } + +/* tnl_print_stats - print tunnel statistics + * + * @buf - tunnel interface's line in /proc/net/dev, + * starting past the interface name and following colon + */ +void tnl_print_stats(const char *buf) +{ + unsigned long rx_bytes, rx_packets, rx_errs, rx_drops, + rx_fifo, rx_frame, + tx_bytes, tx_packets, tx_errs, tx_drops, + tx_fifo, tx_colls, tx_carrier, rx_multi; + + if (sscanf(buf, "%lu%lu%lu%lu%lu%lu%lu%*d%lu%lu%lu%lu%lu%lu%lu", + &rx_bytes, &rx_packets, &rx_errs, &rx_drops, + &rx_fifo, &rx_frame, &rx_multi, + &tx_bytes, &tx_packets, &tx_errs, &tx_drops, + &tx_fifo, &tx_colls, &tx_carrier) != 14) + return; + + printf("%s", _SL_); + printf("RX: Packets Bytes Errors CsumErrs OutOfSeq Mcasts%s", _SL_); + printf(" %-10ld %-12ld %-6ld %-8ld %-8ld %-8ld%s", + rx_packets, rx_bytes, rx_errs, rx_frame, rx_fifo, rx_multi, _SL_); + printf("TX: Packets Bytes Errors DeadLoop NoRoute NoBufs%s", _SL_); + printf(" %-10ld %-12ld %-6ld %-8ld %-8ld %-6ld", + tx_packets, tx_bytes, tx_errs, tx_colls, tx_carrier, tx_drops); +} diff --git a/ip/tunnel.h b/ip/tunnel.h index 9fb4a18..9a03c0d 100644 --- a/ip/tunnel.h +++ b/ip/tunnel.h @@ -32,5 +32,6 @@ int tnl_prl_ioctl(int cmd, const char *name, void *p); int tnl_6rd_ioctl(int cmd, const char *name, void *p); int tnl_ioctl_get_6rd(const char *name, void *p); __be32 tnl_parse_key(const char *name, const char *key); +void tnl_print_stats(const char *buf); #endif |