aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-01-31 19:10:03 -0500
committerDavid S. Miller <davem@davemloft.net>2011-01-31 19:10:03 -0500
commit5b4704419cbd0b7597a91c19f9e8e8b17c1af071 (patch)
tree94ee46905ba2a142bdf910fb26f7450c41ebc46a
parenta5e3c2aae23a3719105c1ae662c67ef282f213db (diff)
ipv4: Remember FIB alias list head and table in lookup results.
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>
-rw-r--r--include/net/ip_fib.h3
-rw-r--r--net/ipv4/fib_hash.c2
-rw-r--r--net/ipv4/fib_lookup.h2
-rw-r--r--net/ipv4/fib_semantics.c7
-rw-r--r--net/ipv4/fib_trie.c8
5 files changed, 14 insertions, 8 deletions
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index 2c0508a6e07c..f5199b08ba53 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -96,12 +96,15 @@ struct fib_info {
96struct fib_rule; 96struct fib_rule;
97#endif 97#endif
98 98
99struct fib_table;
99struct fib_result { 100struct fib_result {
100 unsigned char prefixlen; 101 unsigned char prefixlen;
101 unsigned char nh_sel; 102 unsigned char nh_sel;
102 unsigned char type; 103 unsigned char type;
103 unsigned char scope; 104 unsigned char scope;
104 struct fib_info *fi; 105 struct fib_info *fi;
106 struct fib_table *table;
107 struct list_head *fa_head;
105#ifdef CONFIG_IP_MULTIPLE_TABLES 108#ifdef CONFIG_IP_MULTIPLE_TABLES
106 struct fib_rule *r; 109 struct fib_rule *r;
107#endif 110#endif
diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c
index b3acb0417b21..0a88866ad1e5 100644
--- a/net/ipv4/fib_hash.c
+++ b/net/ipv4/fib_hash.c
@@ -288,7 +288,7 @@ int fib_table_lookup(struct fib_table *tb,
288 if (f->fn_key != k) 288 if (f->fn_key != k)
289 continue; 289 continue;
290 290
291 err = fib_semantic_match(&f->fn_alias, 291 err = fib_semantic_match(tb, &f->fn_alias,
292 flp, res, 292 flp, res,
293 fz->fz_order, fib_flags); 293 fz->fz_order, fib_flags);
294 if (err <= 0) 294 if (err <= 0)
diff --git a/net/ipv4/fib_lookup.h b/net/ipv4/fib_lookup.h
index c079cc0ec651..d5c40d8f6632 100644
--- a/net/ipv4/fib_lookup.h
+++ b/net/ipv4/fib_lookup.h
@@ -25,7 +25,7 @@ static inline void fib_alias_accessed(struct fib_alias *fa)
25} 25}
26 26
27/* Exported by fib_semantics.c */ 27/* Exported by fib_semantics.c */
28extern int fib_semantic_match(struct list_head *head, 28extern int fib_semantic_match(struct fib_table *tb, struct list_head *head,
29 const struct flowi *flp, 29 const struct flowi *flp,
30 struct fib_result *res, int prefixlen, int fib_flags); 30 struct fib_result *res, int prefixlen, int fib_flags);
31extern void fib_release_info(struct fib_info *); 31extern void fib_release_info(struct fib_info *);
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 48e93a560077..1bf6fb906cfc 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -889,8 +889,9 @@ failure:
889} 889}
890 890
891/* Note! fib_semantic_match intentionally uses RCU list functions. */ 891/* Note! fib_semantic_match intentionally uses RCU list functions. */
892int fib_semantic_match(struct list_head *head, const struct flowi *flp, 892int fib_semantic_match(struct fib_table *tb, struct list_head *head,
893 struct fib_result *res, int prefixlen, int fib_flags) 893 const struct flowi *flp, struct fib_result *res,
894 int prefixlen, int fib_flags)
894{ 895{
895 struct fib_alias *fa; 896 struct fib_alias *fa;
896 int nh_sel = 0; 897 int nh_sel = 0;
@@ -954,6 +955,8 @@ out_fill_res:
954 res->type = fa->fa_type; 955 res->type = fa->fa_type;
955 res->scope = fa->fa_scope; 956 res->scope = fa->fa_scope;
956 res->fi = fa->fa_info; 957 res->fi = fa->fa_info;
958 res->table = tb;
959 res->fa_head = head;
957 if (!(fib_flags & FIB_LOOKUP_NOREF)) 960 if (!(fib_flags & FIB_LOOKUP_NOREF))
958 atomic_inc(&res->fi->fib_clntref); 961 atomic_inc(&res->fi->fib_clntref);
959 return 0; 962 return 0;
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 0f280348e0fd..8cee5c8848ed 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -1340,7 +1340,7 @@ err:
1340} 1340}
1341 1341
1342/* should be called with rcu_read_lock */ 1342/* should be called with rcu_read_lock */
1343static int check_leaf(struct trie *t, struct leaf *l, 1343static int check_leaf(struct fib_table *tb, struct trie *t, struct leaf *l,
1344 t_key key, const struct flowi *flp, 1344 t_key key, const struct flowi *flp,
1345 struct fib_result *res, int fib_flags) 1345 struct fib_result *res, int fib_flags)
1346{ 1346{
@@ -1356,7 +1356,7 @@ static int check_leaf(struct trie *t, struct leaf *l,
1356 if (l->key != (key & ntohl(mask))) 1356 if (l->key != (key & ntohl(mask)))
1357 continue; 1357 continue;
1358 1358
1359 err = fib_semantic_match(&li->falh, flp, res, plen, fib_flags); 1359 err = fib_semantic_match(tb, &li->falh, flp, res, plen, fib_flags);
1360 1360
1361#ifdef CONFIG_IP_FIB_TRIE_STATS 1361#ifdef CONFIG_IP_FIB_TRIE_STATS
1362 if (err <= 0) 1362 if (err <= 0)
@@ -1398,7 +1398,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi *flp,
1398 1398
1399 /* Just a leaf? */ 1399 /* Just a leaf? */
1400 if (IS_LEAF(n)) { 1400 if (IS_LEAF(n)) {
1401 ret = check_leaf(t, (struct leaf *)n, key, flp, res, fib_flags); 1401 ret = check_leaf(tb, t, (struct leaf *)n, key, flp, res, fib_flags);
1402 goto found; 1402 goto found;
1403 } 1403 }
1404 1404
@@ -1423,7 +1423,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi *flp,
1423 } 1423 }
1424 1424
1425 if (IS_LEAF(n)) { 1425 if (IS_LEAF(n)) {
1426 ret = check_leaf(t, (struct leaf *)n, key, flp, res, fib_flags); 1426 ret = check_leaf(tb, t, (struct leaf *)n, key, flp, res, fib_flags);
1427 if (ret > 0) 1427 if (ret > 0)
1428 goto backtrace; 1428 goto backtrace;
1429 goto found; 1429 goto found;