]> rtime.felk.cvut.cz Git - lisovros/iproute2_canprio.git/commitdiff
rto support for ip command
authorRick Jones <rick.jones2@hp.com>
Thu, 11 Oct 2007 20:04:11 +0000 (13:04 -0700)
committerStephen Hemminger <shemminger@linux-foundation.org>
Thu, 11 Oct 2007 20:04:11 +0000 (13:04 -0700)
Enable users of ip to specify the times for rtt, rttvar and rto_min
in human-friendly terms a la "tc" while maintaining backwards
compatability with the previous "raw" mechanism.  Builds upon
David Miller's uncommited patch to set rto_min.

Signed-off-by: Rick Jones <rick.jones2@hp.com>
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
include/utils.h
ip/iproute.c
lib/utils.c
man/man8/ip.8

index a3fd3356eceb91faadffed11dd4350fcc439c022..7da2b2964c7cd4cf57a5eaab6dce26b45937c544 100644 (file)
@@ -77,6 +77,7 @@ extern int get_prefix(inet_prefix *dst, char *arg, int family);
 
 extern int get_integer(int *val, const char *arg, int base);
 extern int get_unsigned(unsigned *val, const char *arg, int base);
+extern int get_jiffies(unsigned *val, const char *arg, int base, int *raw);
 #define get_byte get_u8
 #define get_ushort get_u16
 #define get_short get_s16
index 9694bc7b983910f9634aac54da4b9debda9a1976..77bdf83c40043f4a7ee077eb9d0274b2b84c0fc6 100644 (file)
@@ -51,6 +51,7 @@ static const char *mx_names[RTAX_MAX+1] = {
        [RTAX_HOPLIMIT] = "hoplimit",
        [RTAX_INITCWND] = "initcwnd",
        [RTAX_FEATURES] = "features",
+       [RTAX_RTO_MIN]  = "rto_min",
 };
 static void usage(void) __attribute__((noreturn));
 
@@ -71,9 +72,10 @@ static void usage(void)
        fprintf(stderr, "INFO_SPEC := NH OPTIONS FLAGS [ nexthop NH ]...\n");
        fprintf(stderr, "NH := [ via ADDRESS ] [ dev STRING ] [ weight NUMBER ] NHFLAGS\n");
        fprintf(stderr, "OPTIONS := FLAGS [ mtu NUMBER ] [ advmss NUMBER ]\n");
-       fprintf(stderr, "           [ rtt NUMBER ] [ rttvar NUMBER ]\n");
+       fprintf(stderr, "           [ rtt TIME ] [ rttvar TIME ]\n");
        fprintf(stderr, "           [ window NUMBER] [ cwnd NUMBER ] [ initcwnd NUMBER ]\n");
        fprintf(stderr, "           [ ssthresh NUMBER ] [ realms REALM ]\n");
+       fprintf(stderr, "           [ rto_min TIME ]\n");
        fprintf(stderr, "TYPE := [ unicast | local | broadcast | multicast | throw |\n");
        fprintf(stderr, "          unreachable | prohibit | blackhole | nat ]\n");
        fprintf(stderr, "TABLE_ID := [ local | main | default | all | NUMBER ]\n");
@@ -82,6 +84,7 @@ static void usage(void)
        fprintf(stderr, "MP_ALGO := { rr | drr | random | wrandom }\n");
        fprintf(stderr, "NHFLAGS := [ onlink | pervasive ]\n");
        fprintf(stderr, "RTPROTO := [ kernel | boot | static | NUMBER ]\n");
+       fprintf(stderr, "TIME := NUMBER[s|ms|us|ns|j]\n");
        exit(-1);
 }
 
@@ -520,7 +523,8 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
                        if (mxlock & (1<<i))
                                fprintf(fp, " lock");
 
-                       if (i != RTAX_RTT && i != RTAX_RTTVAR)
+                       if (i != RTAX_RTT && i != RTAX_RTTVAR &&
+                           i != RTAX_RTO_MIN)
                                fprintf(fp, " %u", *(unsigned*)RTA_DATA(mxrta[i]));
                        else {
                                unsigned val = *(unsigned*)RTA_DATA(mxrta[i]);
@@ -528,7 +532,7 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
                                val *= 1000;
                                if (i == RTAX_RTT)
                                        val /= 8;
-                               else
+                               else if (i == RTAX_RTTVAR)
                                        val /= 4;
                                if (val >= hz)
                                        fprintf(fp, " %ums", val/hz);
@@ -693,6 +697,7 @@ int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
        int table_ok = 0;
        int proto_ok = 0;
        int type_ok = 0;
+       int raw = 0;
 
        memset(&req, 0, sizeof(req));
 
@@ -800,9 +805,19 @@ int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
                                mxlock |= (1<<RTAX_RTT);
                                NEXT_ARG();
                        }
-                       if (get_unsigned(&rtt, *argv, 0))
+                       if (get_jiffies(&rtt, *argv, 0, &raw))
                                invarg("\"rtt\" value is invalid\n", *argv);
-                       rta_addattr32(mxrta, sizeof(mxbuf), RTAX_RTT, rtt);
+                       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_jiffies(&rto_min, *argv, 0, &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();
@@ -840,9 +855,10 @@ int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
                                mxlock |= (1<<RTAX_RTTVAR);
                                NEXT_ARG();
                        }
-                       if (get_unsigned(&win, *argv, 0))
+                       if (get_jiffies(&win, *argv, 0, &raw))
                                invarg("\"rttvar\" value is invalid\n", *argv);
-                       rta_addattr32(mxrta, sizeof(mxbuf), RTAX_RTTVAR, win);
+                       rta_addattr32(mxrta, sizeof(mxbuf), RTAX_RTTVAR,
+                               (raw) ? win : win * 4);
                } else if (matches(*argv, "ssthresh") == 0) {
                        unsigned win;
                        NEXT_ARG();
index 4f35a60f60d9952e198dc9978811afe777f2b8ea..4c42dfd8b66b6761050f09bd7098df1fadb27c21 100644 (file)
@@ -61,6 +61,70 @@ int get_unsigned(unsigned *val, const char *arg, int base)
        return 0;
 }
 
+/*
+ * get_jiffies is "translated" from a similar routine "get_time" in
+ * tc_util.c.  we don't use the exact same routine because tc passes
+ * microseconds to the kernel and the callers of get_jiffies want 
+ * to pass jiffies, and have a different assumption for the units of
+ * a "raw" number.
+ */
+
+int get_jiffies(unsigned *jiffies, const char *arg, int base, int *raw)
+{
+       double t;
+       unsigned long res;
+       char *p;
+
+       if (strchr(arg,'.') != NULL) {
+               t = strtod(arg,&p);
+               if (t < 0.0)
+                       return -1;
+       }
+       else {
+               res = strtoul(arg,&p,base);
+               if (res > UINT_MAX)
+                       return -1;
+               t = (double)res;
+       }
+       if (p == arg)
+               return -1;
+
+       if (__iproute2_hz_internal == 0)
+                __iproute2_hz_internal = __get_hz();
+       
+       *raw = 1;
+
+       if (*p) {
+               *raw = 0;
+                if (strcasecmp(p, "s") == 0 || strcasecmp(p, "sec")==0 ||
+                    strcasecmp(p, "secs")==0)
+                        t *= __iproute2_hz_internal;
+                else if (strcasecmp(p, "ms") == 0 || strcasecmp(p, "msec")==0 ||
+                         strcasecmp(p, "msecs") == 0)
+                        t *= __iproute2_hz_internal/1000.0;
+                else if (strcasecmp(p, "us") == 0 || strcasecmp(p, "usec")==0 ||
+                         strcasecmp(p, "usecs") == 0)
+                        t *= __iproute2_hz_internal/1000000.0;
+                else if (strcasecmp(p, "ns") == 0 || strcasecmp(p, "nsec")==0 ||
+                         strcasecmp(p, "nsecs") == 0)
+                        t *= __iproute2_hz_internal/1000000000.0;
+               else if (strcasecmp(p, "j") == 0 || strcasecmp(p, "hz") == 0 ||
+                        strcasecmp(p,"jiffies") == 0)
+                       t *= 1.0; /* allow suffix, do nothing */
+                else
+                        return -1;
+        }
+
+       /* emulate ceil() without having to bring-in -lm and always be >= 1 */
+
+       *jiffies = t;
+       if (*jiffies < t)
+               *jiffies += 1;
+       
+        return 0;
+
+}
+
 int get_u64(__u64 *val, const char *arg, int base)
 {
        unsigned long long res;
index a9132da2ce62449c76de935878b9f1981e3448c5..718105459a9e58a1ecb2f55d7e932c0c83aa8cc1 100644 (file)
@@ -169,9 +169,9 @@ replace " | " monitor " } "
 .B  advmss
 .IR NUMBER " ] [ "
 .B  rtt
-.IR NUMBER " ] [ "
+.IR TIME " ] [ "
 .B  rttvar
-.IR NUMBER " ] [ "
+.IR TIME " ] [ "
 .B  window
 .IR NUMBER " ] [ "
 .B  cwnd
@@ -179,7 +179,9 @@ replace " | " monitor " } "
 .B  ssthresh
 .IR REALM " ] [ "
 .B  realms
-.IR REALM " ]"
+.IR REALM " ] [ "
+.B  rto_min
+.IR TIME " ]"
 
 .ti -8
 .IR TYPE " := [ "
@@ -300,6 +302,9 @@ throw " | " unreachable " | " prohibit " | " blackhole " | " nat " ]"
 .ti -8
 .IR KEY " := { " DOTTED_QUAD " | " NUMBER " }"
 
+.ti -8
+.IR TIME " := " NUMBER "[s|ms|us|ns|j]"
+
 .ti -8
 .BR "ip maddr" " [ " add " | " del " ]"
 .IB MULTIADDR " dev " STRING
@@ -1062,12 +1067,29 @@ measured in bytes.  It limits maximal data bursts that our TCP
 peers are allowed to send to us.
 
 .TP
-.BI rtt " NUMBER"
-the initial RTT ('Round Trip Time') estimate.
+.BI rtt " TIME"
+the initial RTT ('Round Trip Time') estimate. If no suffix is
+specified the units are raw values passed directly to the
+routing code to maintain compatability with previous releases.
+Otherwise if a suffix of s, sec or secs is used to specify
+seconds; ms, msec or msecs to specify milliseconds; us, usec 
+or usecs to specify microseconds; ns, nsec or nsecs to specify 
+nanoseconds; j, hz or jiffies to specify jiffies, the value is 
+converted to what the routing code expects.
+
+
+.TP
+.BI rttvar " TIME " "(2.3.15+ only)"
+the initial RTT variance estimate. Values are specified as with 
+.BI rtt
+above.
 
 .TP
-.BI rttvar " NUMBER " "(2.3.15+ only)"
-the initial RTT variance estimate.
+.BI rto_min " TIME " "(2.6.23+ only)"
+the minimum TCP Retransmission TimeOut to use when communicating with this
+destination.  Values are specified as with
+.BI rtt
+above.
 
 .TP
 .BI ssthresh " NUMBER " "(2.3.15+ only)"