diff options
author | 2006-10-31 00:43:44 -0800 | |
---|---|---|
committer | 2006-10-31 00:43:44 -0800 | |
commit | 1b7c2dbc07bf0663a41e3dc838992930019f08fd (patch) | |
tree | 66da0b902159e6f03c8131a21ce8ab1ea7f87097 /net/ipv6/ip6_flowlabel.c | |
parent | [IPV6]: return EINVAL for invalid address with flowlabel lease request (diff) | |
download | linux-1b7c2dbc07bf0663a41e3dc838992930019f08fd.tar.gz linux-1b7c2dbc07bf0663a41e3dc838992930019f08fd.tar.bz2 linux-1b7c2dbc07bf0663a41e3dc838992930019f08fd.zip |
[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/ip6_flowlabel.c')
-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 2b45f2d657c2..6d4533b58dca 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; } |