iproute: update help text, add commented-out code for unsupported options
authorDenys Vlasenko <vda.linux@googlemail.com>
Thu, 6 Apr 2017 15:54:38 +0000 (17:54 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Thu, 6 Apr 2017 15:54:38 +0000 (17:54 +0200)
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 <vda.linux@googlemail.com>
networking/ip.c
networking/libiproute/iproute.c

index 6fc43f65387cf3112fc022c12c922178bf9590f0..155adcfe40b1afd7c56596f69201ac2b60dc6b8e 100644 (file)
 //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"
index 0f2b89682d2e92b50bec8bce1327aceeb2d78ae7..62fa6efd3d6b7cbd07dfd94010fc29271d4734f5 100644 (file)
@@ -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<<RTAX_HOPLIMIT);
+                               NEXT_ARG();
+                       }
+                       if (get_unsigned(&hoplimit, *argv, 0))
+                               invarg("\"hoplimit\" value is invalid\n", *argv);
+                       rta_addattr32(mxrta, sizeof(mxbuf), RTAX_HOPLIMIT, hoplimit);
+               } else if (strcmp(*argv, "advmss") == 0) {
+                       unsigned mss;
+                       NEXT_ARG();
+                       if (strcmp(*argv, "lock") == 0) {
+                               mxlock |= (1<<RTAX_ADVMSS);
+                               NEXT_ARG();
+                       }
+                       if (get_unsigned(&mss, *argv, 0))
+                               invarg("\"mss\" value is invalid\n", *argv);
+                       rta_addattr32(mxrta, sizeof(mxbuf), RTAX_ADVMSS, mss);
+               } else if (matches(*argv, "reordering") == 0) {
+                       unsigned reord;
+                       NEXT_ARG();
+                       if (strcmp(*argv, "lock") == 0) {
+                               mxlock |= (1<<RTAX_REORDERING);
+                               NEXT_ARG();
+                       }
+                       if (get_unsigned(&reord, *argv, 0))
+                               invarg("\"reordering\" value is invalid\n", *argv);
+                       rta_addattr32(mxrta, sizeof(mxbuf), RTAX_REORDERING, reord);
+               } else if (strcmp(*argv, "rtt") == 0) {
+                       unsigned rtt;
+                       NEXT_ARG();
+                       if (strcmp(*argv, "lock") == 0) {
+                               mxlock |= (1<<RTAX_RTT);
+                               NEXT_ARG();
+                       }
+                       if (get_time_rtt(&rtt, *argv, &raw))
+                               invarg("\"rtt\" value is invalid\n", *argv);
+                       rta_addattr32(mxrta, sizeof(mxbuf), RTAX_RTT,
+                               (raw) ? rtt : rtt * 8);
+               } else if (strcmp(*argv, "rto_min") == 0) {
+                       unsigned rto_min;
+                       NEXT_ARG();
+                       mxlock |= (1<<RTAX_RTO_MIN);
+                       if (get_time_rtt(&rto_min, *argv, &raw))
+                               invarg("\"rto_min\" value is invalid\n",
+                                      *argv);
+                       rta_addattr32(mxrta, sizeof(mxbuf), RTAX_RTO_MIN,
+                                     rto_min);
+               } else if (matches(*argv, "window") == 0) {
+                       unsigned win;
+                       NEXT_ARG();
+                       if (strcmp(*argv, "lock") == 0) {
+                               mxlock |= (1<<RTAX_WINDOW);
+                               NEXT_ARG();
+                       }
+                       if (get_unsigned(&win, *argv, 0))
+                               invarg("\"window\" value is invalid\n", *argv);
+                       rta_addattr32(mxrta, sizeof(mxbuf), RTAX_WINDOW, win);
+               } else if (matches(*argv, "cwnd") == 0) {
+                       unsigned win;
+                       NEXT_ARG();
+                       if (strcmp(*argv, "lock") == 0) {
+                               mxlock |= (1<<RTAX_CWND);
+                               NEXT_ARG();
+                       }
+                       if (get_unsigned(&win, *argv, 0))
+                               invarg("\"cwnd\" value is invalid\n", *argv);
+                       rta_addattr32(mxrta, sizeof(mxbuf), RTAX_CWND, win);
+               } else if (matches(*argv, "initcwnd") == 0) {
+                       unsigned win;
+                       NEXT_ARG();
+                       if (strcmp(*argv, "lock") == 0) {
+                               mxlock |= (1<<RTAX_INITCWND);
+                               NEXT_ARG();
+                       }
+                       if (get_unsigned(&win, *argv, 0))
+                               invarg("\"initcwnd\" value is invalid\n", *argv);
+                       rta_addattr32(mxrta, sizeof(mxbuf), RTAX_INITCWND, win);
+               } else if (matches(*argv, "initrwnd") == 0) {
+                       unsigned win;
+                       NEXT_ARG();
+                       if (strcmp(*argv, "lock") == 0) {
+                               mxlock |= (1<<RTAX_INITRWND);
+                               NEXT_ARG();
+                       }
+                       if (get_unsigned(&win, *argv, 0))
+                               invarg("\"initrwnd\" value is invalid\n", *argv);
+                       rta_addattr32(mxrta, sizeof(mxbuf), RTAX_INITRWND, win);
+               } else if (matches(*argv, "features") == 0) {
+                       unsigned int features = 0;
+
+                       while (argc > 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<<RTAX_RTTVAR);
+                               NEXT_ARG();
+                       }
+                       if (get_time_rtt(&win, *argv, &raw))
+                               invarg("\"rttvar\" value is invalid\n", *argv);
+                       rta_addattr32(mxrta, sizeof(mxbuf), RTAX_RTTVAR,
+                               (raw) ? win : win * 4);
+               } else if (matches(*argv, "ssthresh") == 0) {
+                       unsigned win;
+                       NEXT_ARG();
+                       if (strcmp(*argv, "lock") == 0) {
+                               mxlock |= (1<<RTAX_SSTHRESH);
+                               NEXT_ARG();
+                       }
+                       if (get_unsigned(&win, *argv, 0))
+                               invarg("\"ssthresh\" value is invalid\n", *argv);
+                       rta_addattr32(mxrta, sizeof(mxbuf), RTAX_SSTHRESH, win);
+               } else if (matches(*argv, "realms") == 0) {
+                       __u32 realm;
+                       NEXT_ARG();
+                       if (get_rt_realms(&realm, *argv))
+                               invarg("\"realm\" value is invalid\n", *argv);
+                       addattr32(&req.n, sizeof(req), RTA_FLOW, realm);
+               } else if (strcmp(*argv, "nexthop") == 0) {
+                       nhs_ok = 1;
+                       break;
+               }
+#endif
                argv++;
        }