Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=a88ee229253b31e3a844b30525ff77fbfe3111d3
Commit:     a88ee229253b31e3a844b30525ff77fbfe3111d3
Parent:     82cfbb008572b1a953091ef78f767aa3ca213092
Author:     Stephen Hemminger <[EMAIL PROTECTED]>
AuthorDate: Tue Jan 22 21:56:11 2008 -0800
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Mon Jan 28 15:11:00 2008 -0800

    [IPV4] fib_trie: dump table in sorted order
    
    It is easier with TRIE to dump the data traversal rather than
    interating over every possible prefix. This saves some time and makes
    the dump come out in sorted order.
    
    Signed-off-by: Stephen Hemminger <[EMAIL PROTECTED]>
    Signed-off-by: David S. Miller <[EMAIL PROTECTED]>
---
 net/ipv4/fib_trie.c |   74 +++++++++++++++++++++++++++------------------------
 1 files changed, 39 insertions(+), 35 deletions(-)

diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index dab439b..2ea94eb 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -1908,67 +1908,71 @@ static int fn_trie_dump_fa(t_key key, int plen, struct 
list_head *fah,
        return skb->len;
 }
 
-static int fn_trie_dump_plen(struct trie *t, int plen, struct fib_table *tb,
-                            struct sk_buff *skb, struct netlink_callback *cb)
+
+static int fn_trie_dump_leaf(struct leaf *l, struct fib_table *tb,
+                       struct sk_buff *skb, struct netlink_callback *cb)
 {
-       int h, s_h;
-       struct list_head *fa_head;
-       struct leaf *l = NULL;
+       struct leaf_info *li;
+       struct hlist_node *node;
+       int i, s_i;
 
-       s_h = cb->args[3];
-       h = 0;
+       s_i = cb->args[3];
+       i = 0;
 
-       for (l = trie_firstleaf(t); l != NULL; h++, l = trie_nextleaf(l)) {
-               if (h < s_h)
+       /* rcu_read_lock is hold by caller */
+       hlist_for_each_entry_rcu(li, node, &l->list, hlist) {
+               if (i < s_i) {
+                       i++;
                        continue;
-               if (h > s_h)
-                       memset(&cb->args[4], 0,
-                              sizeof(cb->args) - 4*sizeof(cb->args[0]));
-
-               fa_head = get_fa_head(l, plen);
+               }
 
-               if (!fa_head)
-                       continue;
+               if (i > s_i)
+                       cb->args[4] = 0;
 
-               if (list_empty(fa_head))
+               if (list_empty(&li->falh))
                        continue;
 
-               if (fn_trie_dump_fa(l->key, plen, fa_head, tb, skb, cb) < 0) {
-                       cb->args[3] = h;
+               if (fn_trie_dump_fa(l->key, li->plen, &li->falh, tb, skb, cb) < 
0) {
+                       cb->args[3] = i;
                        return -1;
                }
+               i++;
        }
-       cb->args[3] = h;
+
+       cb->args[3] = i;
        return skb->len;
 }
 
+
+
 static int fn_trie_dump(struct fib_table *tb, struct sk_buff *skb,
                        struct netlink_callback *cb)
 {
-       int m, s_m;
+       struct leaf *l;
        struct trie *t = (struct trie *) tb->tb_data;
-
-       s_m = cb->args[2];
+       int h = 0;
+       int s_h = cb->args[2];
 
        rcu_read_lock();
-       for (m = 0; m <= 32; m++) {
-               if (m < s_m)
+       for (h = 0, l = trie_firstleaf(t); l != NULL; h++, l = 
trie_nextleaf(l)) {
+               if (h < s_h)
                        continue;
-               if (m > s_m)
-                       memset(&cb->args[3], 0,
-                               sizeof(cb->args) - 3*sizeof(cb->args[0]));
 
-               if (fn_trie_dump_plen(t, 32-m, tb, skb, cb) < 0) {
-                       cb->args[2] = m;
-                       goto out;
+               if (h > s_h) {
+                       cb->args[3] = 0;
+                       cb->args[4] = 0;
+               }
+
+               if (fn_trie_dump_leaf(l, tb, skb, cb) < 0) {
+                       rcu_read_unlock();
+                       cb->args[2] = h;
+                       return -1;
                }
        }
        rcu_read_unlock();
-       cb->args[2] = m;
+
+       cb->args[2] = h;
        return skb->len;
-out:
-       rcu_read_unlock();
-       return -1;
 }
 
 void __init fib_hash_init(void)
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to