[IPV6]: fix flowlabel seqfile handling
authorJames Morris <jmorris@namei.org>
Tue, 31 Oct 2006 08:43:44 +0000 (00:43 -0800)
committerDavid S. Miller <davem@davemloft.net>
Tue, 31 Oct 2006 08:43:44 +0000 (00:43 -0800)
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>
net/ipv6/ip6_flowlabel.c

index 2b45f2d..6d4533b 100644 (file)
@@ -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;
 }