diff options
author | David S. Miller <davem@davemloft.net> | 2011-01-31 19:10:03 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-01-31 19:10:03 -0500 |
commit | 5b4704419cbd0b7597a91c19f9e8e8b17c1af071 (patch) | |
tree | 94ee46905ba2a142bdf910fb26f7450c41ebc46a | |
parent | a5e3c2aae23a3719105c1ae662c67ef282f213db (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.h | 3 | ||||
-rw-r--r-- | net/ipv4/fib_hash.c | 2 | ||||
-rw-r--r-- | net/ipv4/fib_lookup.h | 2 | ||||
-rw-r--r-- | net/ipv4/fib_semantics.c | 7 | ||||
-rw-r--r-- | net/ipv4/fib_trie.c | 8 |
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 { | |||
96 | struct fib_rule; | 96 | struct fib_rule; |
97 | #endif | 97 | #endif |
98 | 98 | ||
99 | struct fib_table; | ||
99 | struct fib_result { | 100 | struct 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 */ |
28 | extern int fib_semantic_match(struct list_head *head, | 28 | extern 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); |
31 | extern void fib_release_info(struct fib_info *); | 31 | extern 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. */ |
892 | int fib_semantic_match(struct list_head *head, const struct flowi *flp, | 892 | int 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 */ |
1343 | static int check_leaf(struct trie *t, struct leaf *l, | 1343 | static 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; |