Commit 9b2cdc00 authored by Gerrit Renker's avatar Gerrit Renker Committed by Stephen Hemminger

iproute: fix unit conversion of rtt/rttvar/rto_min

Since July 2008 (2.6.27, c1e20f7c8b9), the kernel stores the values for
RTAX_{RTT{,VAR},RTO_MIN} in milliseconds. When using a kernel > 2.6.27 with
the current iproute2, conversion of these values is broken in either way.

This patch
 * updates the code to pass and retrieve milliseconds;
 * since values < 1msec would be rounded up, also drops the usec/nsec variants;
 * since there is no way to query kernel HZ, also drops the jiffies variant.

Arguments such as
	rtt		3.23sec
	rto_min		0xff
	rto_min		0.200s
	rttvar		25ms
now all work as expected when reading back previously set values.
parent 94089ef7
......@@ -85,7 +85,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");
fprintf(stderr, "TIME := NUMBER[s|ms]\n");
exit(-1);
}
......@@ -526,8 +526,6 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
if (mxrta[i] == NULL)
continue;
if (!hz)
hz = get_user_hz();
if (i < sizeof(mx_names)/sizeof(char*) && mx_names[i])
fprintf(fp, " %s", mx_names[i]);
......@@ -549,18 +547,15 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
case RTAX_RTT:
case RTAX_RTTVAR:
case RTAX_RTO_MIN:
val *= 1000;
if (i == RTAX_RTT)
val /= 8;
else if (i == RTAX_RTTVAR)
val /= 4;
if (val >= hz)
fprintf(fp, " %llums",
(unsigned long long) val / hz);
if (val >= 1000)
fprintf(fp, " %gs", val/1e3);
else
fprintf(fp, " %.2fms",
(double)val / hz);
fprintf(fp, " %ums", val);
}
}
}
......
......@@ -119,28 +119,15 @@ int get_jiffies(unsigned *jiffies, const char *arg, int *raw)
}
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;
t *= 1000;
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;
......
......@@ -395,7 +395,7 @@ throw " | " unreachable " | " prohibit " | " blackhole " | " nat " ]"
.IR KEY " := { " DOTTED_QUAD " | " NUMBER " }"
.ti -8
.IR TIME " := " NUMBER "[s|ms|us|ns|j]"
.IR TIME " := " NUMBER "[s|ms]"
.ti -8
.BR "ip maddr" " [ " add " | " del " ]"
......@@ -1638,10 +1638,7 @@ 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 compatibility 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.
seconds and ms, msec or msecs to specify milliseconds.
.TP
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment