diff options
author | Benjamin Thery <benjamin.thery@bull.net> | 2008-12-04 01:21:47 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-12-04 01:21:47 -0500 |
commit | 1ea472e2dedcf23d5f31c63fc790cccfab93c0de (patch) | |
tree | 1886e87c59bc3efe9edee6f2473d5a2ad5b22e9e | |
parent | 9de6d99a7559d20f7ababd1cacdc61ee5315f3c1 (diff) |
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: Benjamin Thery <benjamin.thery@bull.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/ipv4/ipmr.c | 16 | ||||
-rw-r--r-- | net/ipv6/ip6mr.c | 16 |
2 files changed, 22 insertions, 10 deletions
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 77fc4d3fdf61..cb3a57d46af6 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -1879,15 +1879,16 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v) | |||
1879 | const struct mfc_cache *mfc = v; | 1879 | const struct mfc_cache *mfc = v; |
1880 | const struct ipmr_mfc_iter *it = seq->private; | 1880 | const struct ipmr_mfc_iter *it = seq->private; |
1881 | 1881 | ||
1882 | seq_printf(seq, "%08lX %08lX %-3d %8ld %8ld %8ld", | 1882 | seq_printf(seq, "%08lX %08lX %-3d", |
1883 | (unsigned long) mfc->mfc_mcastgrp, | 1883 | (unsigned long) mfc->mfc_mcastgrp, |
1884 | (unsigned long) mfc->mfc_origin, | 1884 | (unsigned long) mfc->mfc_origin, |
1885 | mfc->mfc_parent, | 1885 | mfc->mfc_parent); |
1886 | mfc->mfc_un.res.pkt, | ||
1887 | mfc->mfc_un.res.bytes, | ||
1888 | mfc->mfc_un.res.wrong_if); | ||
1889 | 1886 | ||
1890 | if (it->cache != &mfc_unres_queue) { | 1887 | if (it->cache != &mfc_unres_queue) { |
1888 | seq_printf(seq, " %8lu %8lu %8lu", | ||
1889 | mfc->mfc_un.res.pkt, | ||
1890 | mfc->mfc_un.res.bytes, | ||
1891 | mfc->mfc_un.res.wrong_if); | ||
1891 | for (n = mfc->mfc_un.res.minvif; | 1892 | for (n = mfc->mfc_un.res.minvif; |
1892 | n < mfc->mfc_un.res.maxvif; n++ ) { | 1893 | n < mfc->mfc_un.res.maxvif; n++ ) { |
1893 | if (VIF_EXISTS(n) | 1894 | if (VIF_EXISTS(n) |
@@ -1896,6 +1897,11 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v) | |||
1896 | " %2d:%-3d", | 1897 | " %2d:%-3d", |
1897 | n, mfc->mfc_un.res.ttls[n]); | 1898 | n, mfc->mfc_un.res.ttls[n]); |
1898 | } | 1899 | } |
1900 | } else { | ||
1901 | /* unresolved mfc_caches don't contain | ||
1902 | * pkt, bytes and wrong_if values | ||
1903 | */ | ||
1904 | seq_printf(seq, " %8lu %8lu %8lu", 0ul, 0ul, 0ul); | ||
1899 | } | 1905 | } |
1900 | seq_putc(seq, '\n'); | 1906 | seq_putc(seq, '\n'); |
1901 | } | 1907 | } |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index dfba9fd0c248..2dc4b0190878 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -297,14 +297,15 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v) | |||
297 | const struct mfc6_cache *mfc = v; | 297 | const struct mfc6_cache *mfc = v; |
298 | const struct ipmr_mfc_iter *it = seq->private; | 298 | const struct ipmr_mfc_iter *it = seq->private; |
299 | 299 | ||
300 | seq_printf(seq, "%pI6 %pI6 %-3d %8ld %8ld %8ld", | 300 | seq_printf(seq, "%pI6 %pI6 %-3d", |
301 | &mfc->mf6c_mcastgrp, &mfc->mf6c_origin, | 301 | &mfc->mf6c_mcastgrp, &mfc->mf6c_origin, |
302 | mfc->mf6c_parent, | 302 | mfc->mf6c_parent); |
303 | mfc->mfc_un.res.pkt, | ||
304 | mfc->mfc_un.res.bytes, | ||
305 | mfc->mfc_un.res.wrong_if); | ||
306 | 303 | ||
307 | if (it->cache != &mfc_unres_queue) { | 304 | if (it->cache != &mfc_unres_queue) { |
305 | seq_printf(seq, " %8lu %8lu %8lu", | ||
306 | mfc->mfc_un.res.pkt, | ||
307 | mfc->mfc_un.res.bytes, | ||
308 | mfc->mfc_un.res.wrong_if); | ||
308 | for (n = mfc->mfc_un.res.minvif; | 309 | for (n = mfc->mfc_un.res.minvif; |
309 | n < mfc->mfc_un.res.maxvif; n++) { | 310 | n < mfc->mfc_un.res.maxvif; n++) { |
310 | if (MIF_EXISTS(n) && | 311 | if (MIF_EXISTS(n) && |
@@ -313,6 +314,11 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v) | |||
313 | " %2d:%-3d", | 314 | " %2d:%-3d", |
314 | n, mfc->mfc_un.res.ttls[n]); | 315 | n, mfc->mfc_un.res.ttls[n]); |
315 | } | 316 | } |
317 | } else { | ||
318 | /* unresolved mfc_caches don't contain | ||
319 | * pkt, bytes and wrong_if values | ||
320 | */ | ||
321 | seq_printf(seq, " %8lu %8lu %8lu", 0ul, 0ul, 0ul); | ||
316 | } | 322 | } |
317 | seq_putc(seq, '\n'); | 323 | seq_putc(seq, '\n'); |
318 | } | 324 | } |