From ff2e5a2ada6196ce4ed89a76b5e86f047c9a63f4 Mon Sep 17 00:00:00 2001 From: Marius Tomaschewski Date: Wed, 12 Jan 2011 16:41:45 +0100 Subject: [PATCH] ip route rtt metrics time unit is milliseconds Adopted ip route rtt,rttvar,rto_min metrics time unit to milliseconds instead of jiffies as required by recent kernels (>=2.6.27). Added an get_rtt_metrics_units function providing the unit and the get_time_in_units as successor of get_jiffies function, allowing to specify the unit. The get_rtt_metrics_units can be extended to detect and handle also older kernels. This fixes also the inconsistent use of get_user_hz in print_route and get_hz in get_jiffies function that return different units. --- include/utils.h | 1 + ip/iproute.c | 38 ++++++++++++++++++++++++++------------ lib/utils.c | 24 +++++++++++++----------- 3 files changed, 40 insertions(+), 23 deletions(-) diff --git a/include/utils.h b/include/utils.h index 3da6998..3d98c01 100644 --- a/include/utils.h +++ b/include/utils.h @@ -80,6 +80,7 @@ extern int mask2bits(__u32 netmask); 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); +extern int get_time_in_units(unsigned *val, const char *arg, int base, int *raw, unsigned unit); #define get_byte get_u8 #define get_ushort get_u16 #define get_short get_s16 diff --git a/ip/iproute.c b/ip/iproute.c index 0d69290..830b0a3 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -33,6 +33,21 @@ #define RTAX_RTTVAR RTAX_HOPS #endif +#define TIME_UNIT_MS 1000 + +static unsigned get_rtt_metrics_units(void) +{ + /* + * recent kernels (>=2.6.27) are using milliseconds base. + * Note: To support older kernels, return the proper HZ... + * + * final unit for rto_min: unit + * rttvar: unit * 4 + * rtt: unit * 8 + */ + return TIME_UNIT_MS; +} + enum list_action { IPROUTE_LIST, IPROUTE_FLUSH, @@ -522,12 +537,11 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) mxlock = *(unsigned*)RTA_DATA(mxrta[RTAX_LOCK]); for (i=2; i<= RTAX_MAX; i++) { - unsigned val; + unsigned long long val; /* val *= 1000 below */ + unsigned unit = get_rtt_metrics_units(); 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]); @@ -543,24 +557,24 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) val = 0; /* fall through */ default: - fprintf(fp, " %u", val); + fprintf(fp, " %llu", val); break; case RTAX_RTT: case RTAX_RTTVAR: case RTAX_RTO_MIN: - val *= 1000; + val *= TIME_UNIT_MS; if (i == RTAX_RTT) val /= 8; else if (i == RTAX_RTTVAR) val /= 4; - if (val >= hz) + if (val >= unit) fprintf(fp, " %llums", - (unsigned long long) val / hz); + val / unit); else - fprintf(fp, " %.2fms", - (double)val / hz); + fprintf(fp, " %.8fms", + (double)val / unit); } } } @@ -840,7 +854,7 @@ int iproute_modify(int cmd, unsigned flags, int argc, char **argv) mxlock |= (1<= 1 */ - *jiffies = t; - if (*jiffies < t) - *jiffies += 1; + *val = t; + if (*val < t) + *val += 1; return 0; -- 1.7.1