Commit 1ea472e2 authored by Benjamin Thery's avatar Benjamin Thery Committed by David S. Miller

net: fix /proc/net/ip_mr_cache display - V2

/proc/net/ip_mr_cache and /proc/net/ip6_mr_cache displays garbage when
showing unresolved mfc_cache entries.

[root@qemu tests]# cat /proc/net/ip_mr_cache
Group    Origin   Iif     Pkts    Bytes    Wrong Oifs
014C00EF 010014AC 1         10    10050        0  2:1    3:1
024C00EF 010014AC 65535      514        2 -559067475

The first line is correct. It is a resolved cache entry, 10 packets used it...
The second line represents an unresolved entry, and the columns Pkts(4th),
Bytes(5th) and Wrong(6th) just show garbage.

In struct mfc_cache, there's an union to store data for resolved and
unresolved cases. And what ipmr_mfc_seq_show() is printing in these 
columns for the unresolved entries is some bytes from mfc_cache.mfc_un.res.
Bad.
(eg. In our case -559067475 is in fact 0xdead4ead which is the spinlock
magic from mfc_cache.mfc_un.unres.unresolved.lock.magic).

This patch replaces the garbage data written in these columns for the
unresolved entries by '0' (zeros) which is more correct.
This change doesn't break the ABI.

Also, mfc->mfc_un.res.pkt, mfc->mfc_un.res.bytes, mfc->mfc_un.res.wrong_if
are unsigned long.

It applies on top of net-next-2.6.

The patch for net-2.6 is slightly different because of the NIP6_FMT to
%pI6 conversion that was made in the seq_printf.

Changelog:
==========
V2:
* Instead of breaking the ABI by suppressing the columns that have no
  meaning for unresolved entries, fill them with 0 values.
Signed-off-by: default avatarBenjamin Thery <benjamin.thery@bull.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 9de6d99a
...@@ -1879,15 +1879,16 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v) ...@@ -1879,15 +1879,16 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v)
const struct mfc_cache *mfc = v; const struct mfc_cache *mfc = v;
const struct ipmr_mfc_iter *it = seq->private; const struct ipmr_mfc_iter *it = seq->private;
seq_printf(seq, "%08lX %08lX %-3d %8ld %8ld %8ld", seq_printf(seq, "%08lX %08lX %-3d",
(unsigned long) mfc->mfc_mcastgrp, (unsigned long) mfc->mfc_mcastgrp,
(unsigned long) mfc->mfc_origin, (unsigned long) mfc->mfc_origin,
mfc->mfc_parent, mfc->mfc_parent);
mfc->mfc_un.res.pkt,
mfc->mfc_un.res.bytes,
mfc->mfc_un.res.wrong_if);
if (it->cache != &mfc_unres_queue) { if (it->cache != &mfc_unres_queue) {
seq_printf(seq, " %8lu %8lu %8lu",
mfc->mfc_un.res.pkt,
mfc->mfc_un.res.bytes,
mfc->mfc_un.res.wrong_if);
for (n = mfc->mfc_un.res.minvif; for (n = mfc->mfc_un.res.minvif;
n < mfc->mfc_un.res.maxvif; n++ ) { n < mfc->mfc_un.res.maxvif; n++ ) {
if (VIF_EXISTS(n) if (VIF_EXISTS(n)
...@@ -1896,6 +1897,11 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v) ...@@ -1896,6 +1897,11 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v)
" %2d:%-3d", " %2d:%-3d",
n, mfc->mfc_un.res.ttls[n]); n, mfc->mfc_un.res.ttls[n]);
} }
} else {
/* unresolved mfc_caches don't contain
* pkt, bytes and wrong_if values
*/
seq_printf(seq, " %8lu %8lu %8lu", 0ul, 0ul, 0ul);
} }
seq_putc(seq, '\n'); seq_putc(seq, '\n');
} }
......
...@@ -297,14 +297,15 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v) ...@@ -297,14 +297,15 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v)
const struct mfc6_cache *mfc = v; const struct mfc6_cache *mfc = v;
const struct ipmr_mfc_iter *it = seq->private; const struct ipmr_mfc_iter *it = seq->private;
seq_printf(seq, "%pI6 %pI6 %-3d %8ld %8ld %8ld", seq_printf(seq, "%pI6 %pI6 %-3d",
&mfc->mf6c_mcastgrp, &mfc->mf6c_origin, &mfc->mf6c_mcastgrp, &mfc->mf6c_origin,
mfc->mf6c_parent, mfc->mf6c_parent);
mfc->mfc_un.res.pkt,
mfc->mfc_un.res.bytes,
mfc->mfc_un.res.wrong_if);
if (it->cache != &mfc_unres_queue) { if (it->cache != &mfc_unres_queue) {
seq_printf(seq, " %8lu %8lu %8lu",
mfc->mfc_un.res.pkt,
mfc->mfc_un.res.bytes,
mfc->mfc_un.res.wrong_if);
for (n = mfc->mfc_un.res.minvif; for (n = mfc->mfc_un.res.minvif;
n < mfc->mfc_un.res.maxvif; n++) { n < mfc->mfc_un.res.maxvif; n++) {
if (MIF_EXISTS(n) && if (MIF_EXISTS(n) &&
...@@ -313,6 +314,11 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v) ...@@ -313,6 +314,11 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v)
" %2d:%-3d", " %2d:%-3d",
n, mfc->mfc_un.res.ttls[n]); n, mfc->mfc_un.res.ttls[n]);
} }
} else {
/* unresolved mfc_caches don't contain
* pkt, bytes and wrong_if values
*/
seq_printf(seq, " %8lu %8lu %8lu", 0ul, 0ul, 0ul);
} }
seq_putc(seq, '\n'); seq_putc(seq, '\n');
} }
......
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