ipv4: Remember FIB alias list head and table in lookup results.
authorDavid S. Miller <davem@davemloft.net>
Tue, 1 Feb 2011 00:10:03 +0000 (16:10 -0800)
committerDavid S. Miller <davem@davemloft.net>
Tue, 1 Feb 2011 00:10:03 +0000 (16:10 -0800)
This will be used later to implement fib_select_default() in a
completely generic manner, instead of the current situation where the
default route is re-looked up in the TRIE/HASH table and then the
available aliases are analyzed.

Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/ip_fib.h
net/ipv4/fib_hash.c
net/ipv4/fib_lookup.h
net/ipv4/fib_semantics.c
net/ipv4/fib_trie.c

index 2c0508a6e07c9354587e6f0a857950e30cbc34af..f5199b08ba532610233c578c28dd271414770e1d 100644 (file)
@@ -96,12 +96,15 @@ struct fib_info {
 struct fib_rule;
 #endif
 
+struct fib_table;
 struct fib_result {
        unsigned char   prefixlen;
        unsigned char   nh_sel;
        unsigned char   type;
        unsigned char   scope;
        struct fib_info *fi;
+       struct fib_table *table;
+       struct list_head *fa_head;
 #ifdef CONFIG_IP_MULTIPLE_TABLES
        struct fib_rule *r;
 #endif
index b3acb0417b21f69b754003f76168f30f78b85700..0a88866ad1e5fd8a6a196e2d77468c066788491f 100644 (file)
@@ -288,7 +288,7 @@ int fib_table_lookup(struct fib_table *tb,
                                if (f->fn_key != k)
                                        continue;
 
-                               err = fib_semantic_match(&f->fn_alias,
+                               err = fib_semantic_match(tb, &f->fn_alias,
                                                 flp, res,
                                                 fz->fz_order, fib_flags);
                                if (err <= 0)
index c079cc0ec6515fe212aecd27303c2b5671a5d60d..d5c40d8f6632bce200f42e6fd17545b7c01205d5 100644 (file)
@@ -25,7 +25,7 @@ static inline void fib_alias_accessed(struct fib_alias *fa)
 }
 
 /* Exported by fib_semantics.c */
-extern int fib_semantic_match(struct list_head *head,
+extern int fib_semantic_match(struct fib_table *tb, struct list_head *head,
                              const struct flowi *flp,
                              struct fib_result *res, int prefixlen, int fib_flags);
 extern void fib_release_info(struct fib_info *);
index 48e93a56007708c7d346c2b8ffaed23354466435..1bf6fb906cfc249c8c08924043c6e1adeeec85de 100644 (file)
@@ -889,8 +889,9 @@ failure:
 }
 
 /* Note! fib_semantic_match intentionally uses  RCU list functions. */
-int fib_semantic_match(struct list_head *head, const struct flowi *flp,
-                      struct fib_result *res, int prefixlen, int fib_flags)
+int fib_semantic_match(struct fib_table *tb, struct list_head *head,
+                      const struct flowi *flp, struct fib_result *res,
+                      int prefixlen, int fib_flags)
 {
        struct fib_alias *fa;
        int nh_sel = 0;
@@ -954,6 +955,8 @@ out_fill_res:
        res->type = fa->fa_type;
        res->scope = fa->fa_scope;
        res->fi = fa->fa_info;
+       res->table = tb;
+       res->fa_head = head;
        if (!(fib_flags & FIB_LOOKUP_NOREF))
                atomic_inc(&res->fi->fib_clntref);
        return 0;
index 0f280348e0fdad70adb37f3b33bdbe6fedd99025..8cee5c8848ed5021ce497006eb0e0fa7e90c7122 100644 (file)
@@ -1340,7 +1340,7 @@ err:
 }
 
 /* should be called with rcu_read_lock */
-static int check_leaf(struct trie *t, struct leaf *l,
+static int check_leaf(struct fib_table *tb, struct trie *t, struct leaf *l,
                      t_key key,  const struct flowi *flp,
                      struct fib_result *res, int fib_flags)
 {
@@ -1356,7 +1356,7 @@ static int check_leaf(struct trie *t, struct leaf *l,
                if (l->key != (key & ntohl(mask)))
                        continue;
 
-               err = fib_semantic_match(&li->falh, flp, res, plen, fib_flags);
+               err = fib_semantic_match(tb, &li->falh, flp, res, plen, fib_flags);
 
 #ifdef CONFIG_IP_FIB_TRIE_STATS
                if (err <= 0)
@@ -1398,7 +1398,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi *flp,
 
        /* Just a leaf? */
        if (IS_LEAF(n)) {
-               ret = check_leaf(t, (struct leaf *)n, key, flp, res, fib_flags);
+               ret = check_leaf(tb, t, (struct leaf *)n, key, flp, res, fib_flags);
                goto found;
        }
 
@@ -1423,7 +1423,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi *flp,
                }
 
                if (IS_LEAF(n)) {
-                       ret = check_leaf(t, (struct leaf *)n, key, flp, res, fib_flags);
+                       ret = check_leaf(tb, t, (struct leaf *)n, key, flp, res, fib_flags);
                        if (ret > 0)
                                goto backtrace;
                        goto found;