Commit e5f1be13 authored by Jiri Popelka's avatar Jiri Popelka

ifconfig can incorrectly round PiB

When an interface has transferred exbibytes
(> 0.8 EiB, i.e. > 819 PiB) of traffic,
the short display is rounded incorrectly.

For example:
bytes 2154408931384050514 (275.0 PiB)
while correct is (1913.4 PiB)

This happens because we times the rx/tx bytes values by 10,
then calculate the short version from that result:

lib/interface.c:ife_print_long()

tx = ptr->stats.tx_bytes;
short_tx = tx * 10;
if (tx > 1125899906842624ull) {
  short_tx /= 1125899906842624ull;
  Text = "PiB";
}

But multiplying anything more than 819 PiB by 10 overflows a ull
which is a uint64_t (max value of 9223372036854775807).

We'll never get accuracy over 8192 PiB (2^64) when using ull,
but we can at least correctly handle values between 819 - 8192 PiB.
parent 25b3c9a6
......@@ -867,7 +867,10 @@ void ife_print_long(struct interface *ptr)
rx = ptr->stats.rx_bytes;
short_rx = rx * 10;
if (rx > 1125899906842624ull) {
short_rx /= 1125899906842624ull;
if (rx > (9223372036854775807ull / 10))
short_rx = rx / 112589990684262ull;
else
short_rx /= 1125899906842624ull;
Rext = "PiB";
} else if (rx > 1099511627776ull) {
short_rx /= 1099511627776ull;
......@@ -885,7 +888,10 @@ void ife_print_long(struct interface *ptr)
tx = ptr->stats.tx_bytes;
short_tx = tx * 10;
if (tx > 1125899906842624ull) {
short_tx /= 1125899906842624ull;
if (tx > (9223372036854775807ull / 10))
short_tx = tx / 112589990684262ull;
else
short_tx /= 1125899906842624ull;
Text = "PiB";
} else if (tx > 1099511627776ull) {
short_tx /= 1099511627776ull;
......
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