aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Thery <benjamin.thery@bull.net>2008-12-04 01:21:47 -0500
committerDavid S. Miller <davem@davemloft.net>2008-12-04 01:21:47 -0500
commit1ea472e2dedcf23d5f31c63fc790cccfab93c0de (patch)
tree1886e87c59bc3efe9edee6f2473d5a2ad5b22e9e
parent9de6d99a7559d20f7ababd1cacdc61ee5315f3c1 (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.c16
-rw-r--r--net/ipv6/ip6mr.c16
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 }