diff options
author | James Morris <jmorris@namei.org> | 2006-10-31 00:43:44 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2006-10-31 00:43:44 -0800 |
commit | 1b7c2dbc07bf0663a41e3dc838992930019f08fd (patch) | |
tree | 66da0b902159e6f03c8131a21ce8ab1ea7f87097 /net/ipv6 | |
parent | c6817e4c32d8c4118405d2dec30ac1c264349085 (diff) |
[IPV6]: fix flowlabel seqfile handling
There's a bug in the seqfile show operation for flowlabel objects, where
each hash chain is traversed cumulatively for each element. The following
function is called for each element of each chain:
static void ip6fl_fl_seq_show(struct seq_file *seq, struct ip6_flowlabel *fl)
{
while(fl) {
seq_printf...
fl = fl->next;
}
}
Thus, objects can appear mutliple times when reading
/proc/net/ip6_flowlabel, as the above is called for each element in the
chain.
The solution is to remove the while() loop from the above, and traverse
each chain exactly once, per the patch below. This also removes the
ip6fl_fl_seq_show() function, which does nothing else.
Signed-off-by: James Morris <jmorris@namei.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/ip6_flowlabel.c | 18 |
1 files changed, 6 insertions, 12 deletions
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index 2b45f2d657c..6d4533b58dc 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c @@ -627,9 +627,13 @@ static void ip6fl_seq_stop(struct seq_file *seq, void *v) read_unlock_bh(&ip6_fl_lock); } -static void ip6fl_fl_seq_show(struct seq_file *seq, struct ip6_flowlabel *fl) +static int ip6fl_seq_show(struct seq_file *seq, void *v) { - while(fl) { + if (v == SEQ_START_TOKEN) + seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-32s %s\n", + "Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt"); + else { + struct ip6_flowlabel *fl = v; seq_printf(seq, "%05X %-1d %-6d %-6d %-6ld %-8ld " NIP6_SEQFMT " %-4d\n", (unsigned)ntohl(fl->label), @@ -640,17 +644,7 @@ static void ip6fl_fl_seq_show(struct seq_file *seq, struct ip6_flowlabel *fl) (long)(fl->expires - jiffies)/HZ, NIP6(fl->dst), fl->opt ? fl->opt->opt_nflen : 0); - fl = fl->next; } -} - -static int ip6fl_seq_show(struct seq_file *seq, void *v) -{ - if (v == SEQ_START_TOKEN) - seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-32s %s\n", - "Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt"); - else - ip6fl_fl_seq_show(seq, v); return 0; } |