From 1140bf39ab113aefee8079755fac618bf6314db6 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 6 Apr 2017 17:54:38 +0200 Subject: iproute: update help text, add commented-out code for unsupported options function old new delta packed_usage 31327 31372 +45 do_iproute 132 157 +25 iproute_modify 1162 1164 +2 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 3/0 up/down: 72/0) Total: 72 bytes Signed-off-by: Denys Vlasenko --- networking/ip.c | 39 ++++++++- networking/libiproute/iproute.c | 170 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 202 insertions(+), 7 deletions(-) diff --git a/networking/ip.c b/networking/ip.c index 6fc43f653..155adcfe4 100644 --- a/networking/ip.c +++ b/networking/ip.c @@ -162,11 +162,42 @@ //usage: "list|flush|add|del|change|append|replace|test ROUTE" //usage:#define iproute_full_usage "\n\n" //usage: "iproute list|flush SELECTOR\n" -//usage: "iproute get ADDRESS [from ADDRESS iif STRING]\n" -//usage: " [oif STRING] [tos TOS]\n" -//usage: "iproute add|del|change|append|replace|test ROUTE\n" //usage: " SELECTOR := [root PREFIX] [match PREFIX] [proto RTPROTO]\n" -//usage: " ROUTE := [TYPE] PREFIX [tos TOS] [proto RTPROTO] [metric METRIC]" +//usage: " PREFIX := default|ADDRESS/MASK\n" +//usage: "iproute get ADDRESS [from ADDRESS iif IFACE]\n" +//usage: " [oif IFACE] [tos TOS]\n" +//usage: "iproute add|del|change|append|replace|test ROUTE\n" +//usage: " ROUTE := NODE_SPEC [INFO_SPEC]\n" +//usage: " NODE_SPEC := PREFIX"IF_FEATURE_IP_RULE(" [table TABLE_ID]")" [proto RTPROTO] [scope SCOPE] [metric METRIC]\n" +//usage: " INFO_SPEC := NH OPTIONS\n" +//usage: " NH := [via [inet|inet6] ADDRESS] [dev IFACE] [src ADDRESS] [onlink]\n" +//usage: " OPTIONS := [mtu NUM]" +//upstream man ip-route: +//====================== +//ip route { show | flush } SELECTOR +//ip route save SELECTOR +//ip route restore +//ip route get ADDRESS [ from ADDRESS iif STRING ] [ oif STRING ] [ tos TOS ] +//ip route { add | del | change | append | replace } ROUTE +//SELECTOR := [ root PREFIX ] [ match PREFIX ] [ exact PREFIX ] [ table TABLE_ID ] [ proto RTPROTO ] [ type TYPE ] [ scope SCOPE ] +//ROUTE := NODE_SPEC [ INFO_SPEC ] +//NODE_SPEC := [ TYPE ] PREFIX [ tos TOS ] [ table TABLE_ID ] [ proto RTPROTO ] [ scope SCOPE ] [ metric METRIC ] +//INFO_SPEC := NH OPTIONS FLAGS [ nexthop NH ] ... +//NH := [ encap ENCAP ] [ via [ FAMILY ] ADDRESS ] [ dev STRING ] [ weight NUMBER ] NHFLAGS +// ..............................................................^ I guess [src ADDRESS] should be here +//FAMILY := [ inet | inet6 | ipx | dnet | mpls | bridge | link ] +//OPTIONS := FLAGS [ mtu NUMBER ] [ advmss NUMBER ] [ as [ to ] ADDRESS ] rtt TIME ] [ rttvar TIME ] [ reordering NUMBER ] [ window NUMBER ] [ cwnd NUMBER ] [ ssthresh REALM ] [ realms REALM ] +// [ rto_min TIME ] [ initcwnd NUMBER ] [ initrwnd NUMBER ] [ features FEATURES ] [ quickack BOOL ] [ congctl NAME ] [ pref PREF ] [ expires TIME ] +//TYPE := [ unicast | local | broadcast | multicast | throw | unreachable | prohibit | blackhole | nat ] +//TABLE_ID := [ local | main | default | all | NUMBER ] +//SCOPE := [ host | link | global | NUMBER ] +//NHFLAGS := [ onlink | pervasive ] +//RTPROTO := [ kernel | boot | static | NUMBER ] +//FEATURES := [ ecn | ] +//PREF := [ low | medium | high ] +//ENCAP := [ MPLS | IP ] +//ENCAP_MPLS := mpls [ LABEL ] +//ENCAP_IP := ip id TUNNEL_ID dst REMOTE_IP [ tos TOS ] [ ttl TTL ] //usage: //usage:#define iprule_trivial_usage //usage: "[list] | add|del SELECTOR ACTION" diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c index 0f2b89682..62fa6efd3 100644 --- a/networking/libiproute/iproute.c +++ b/networking/libiproute/iproute.c @@ -325,13 +325,14 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, /* Return value becomes exitcode. It's okay to not return at all */ static int iproute_modify(int cmd, unsigned flags, char **argv) { + /* If you add stuff here, update iproute_full_usage */ static const char keywords[] ALIGN1 = - "src\0""via\0""mtu\0""lock\0""scope\0""protocol\0"IF_FEATURE_IP_RULE("table\0") + "src\0""via\0""mtu\0""scope\0""protocol\0"IF_FEATURE_IP_RULE("table\0") "dev\0""oif\0""to\0""metric\0""onlink\0"; enum { ARG_src, ARG_via, - ARG_mtu, PARM_lock, + ARG_mtu, ARG_scope, ARG_protocol, IF_FEATURE_IP_RULE(ARG_table,) @@ -404,7 +405,7 @@ IF_FEATURE_IP_RULE(ARG_table,) } else if (arg == ARG_mtu) { unsigned mtu; NEXT_ARG(); - if (index_in_strings(keywords, *argv) == PARM_lock) { + if (strcmp(*argv, "lock") == 0) { mxlock |= (1 << RTAX_MTU); NEXT_ARG(); } @@ -441,6 +442,7 @@ IF_FEATURE_IP_RULE(ARG_table,) NEXT_ARG(); d = *argv; } else if (arg == ARG_metric) { +//TODO: "metric", "priority" and "preference" are synonyms uint32_t metric; NEXT_ARG(); metric = get_u32(*argv, "metric"); @@ -475,6 +477,168 @@ IF_FEATURE_IP_RULE(ARG_table,) addattr_l(&req.n, sizeof(req), RTA_DST, &dst.data, dst.bytelen); } } +/* Other keywords recognized by iproute2-3.19.0: */ +#if 0 + } else if (strcmp(*argv, "from") == 0) { + inet_prefix addr; + NEXT_ARG(); + get_prefix(&addr, *argv, req.r.rtm_family); + if (req.r.rtm_family == AF_UNSPEC) + req.r.rtm_family = addr.family; + if (addr.bytelen) + addattr_l(&req.n, sizeof(req), RTA_SRC, &addr.data, addr.bytelen); + req.r.rtm_src_len = addr.bitlen; + } else if (strcmp(*argv, "tos") == 0 || + matches(*argv, "dsfield") == 0) { + __u32 tos; + NEXT_ARG(); + if (rtnl_dsfield_a2n(&tos, *argv)) + invarg("\"tos\" value is invalid\n", *argv); + req.r.rtm_tos = tos; + } else if (strcmp(*argv, "hoplimit") == 0) { + unsigned hoplimit; + NEXT_ARG(); + if (strcmp(*argv, "lock") == 0) { + mxlock |= (1< 0) { + NEXT_ARG(); + + if (strcmp(*argv, "ecn") == 0) + features |= RTAX_FEATURE_ECN; + else + invarg("\"features\" value not valid\n", *argv); + break; + } + + rta_addattr32(mxrta, sizeof(mxbuf), RTAX_FEATURES, features); + } else if (matches(*argv, "quickack") == 0) { + unsigned quickack; + NEXT_ARG(); + if (get_unsigned(&quickack, *argv, 0)) + invarg("\"quickack\" value is invalid\n", *argv); + if (quickack != 1 && quickack != 0) + invarg("\"quickack\" value should be 0 or 1\n", *argv); + rta_addattr32(mxrta, sizeof(mxbuf), RTAX_QUICKACK, quickack); + } else if (matches(*argv, "rttvar") == 0) { + unsigned win; + NEXT_ARG(); + if (strcmp(*argv, "lock") == 0) { + mxlock |= (1<