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>
This commit is contained in:
@@ -96,12 +96,15 @@ struct fib_info {
|
|||||||
struct fib_rule;
|
struct fib_rule;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct fib_table;
|
||||||
struct fib_result {
|
struct fib_result {
|
||||||
unsigned char prefixlen;
|
unsigned char prefixlen;
|
||||||
unsigned char nh_sel;
|
unsigned char nh_sel;
|
||||||
unsigned char type;
|
unsigned char type;
|
||||||
unsigned char scope;
|
unsigned char scope;
|
||||||
struct fib_info *fi;
|
struct fib_info *fi;
|
||||||
|
struct fib_table *table;
|
||||||
|
struct list_head *fa_head;
|
||||||
#ifdef CONFIG_IP_MULTIPLE_TABLES
|
#ifdef CONFIG_IP_MULTIPLE_TABLES
|
||||||
struct fib_rule *r;
|
struct fib_rule *r;
|
||||||
#endif
|
#endif
|
||||||
|
@@ -288,7 +288,7 @@ int fib_table_lookup(struct fib_table *tb,
|
|||||||
if (f->fn_key != k)
|
if (f->fn_key != k)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
err = fib_semantic_match(&f->fn_alias,
|
err = fib_semantic_match(tb, &f->fn_alias,
|
||||||
flp, res,
|
flp, res,
|
||||||
fz->fz_order, fib_flags);
|
fz->fz_order, fib_flags);
|
||||||
if (err <= 0)
|
if (err <= 0)
|
||||||
|
@@ -25,7 +25,7 @@ static inline void fib_alias_accessed(struct fib_alias *fa)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Exported by fib_semantics.c */
|
/* 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,
|
const struct flowi *flp,
|
||||||
struct fib_result *res, int prefixlen, int fib_flags);
|
struct fib_result *res, int prefixlen, int fib_flags);
|
||||||
extern void fib_release_info(struct fib_info *);
|
extern void fib_release_info(struct fib_info *);
|
||||||
|
@@ -889,8 +889,9 @@ failure:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Note! fib_semantic_match intentionally uses RCU list functions. */
|
/* Note! fib_semantic_match intentionally uses RCU list functions. */
|
||||||
int fib_semantic_match(struct list_head *head, const struct flowi *flp,
|
int fib_semantic_match(struct fib_table *tb, struct list_head *head,
|
||||||
struct fib_result *res, int prefixlen, int fib_flags)
|
const struct flowi *flp, struct fib_result *res,
|
||||||
|
int prefixlen, int fib_flags)
|
||||||
{
|
{
|
||||||
struct fib_alias *fa;
|
struct fib_alias *fa;
|
||||||
int nh_sel = 0;
|
int nh_sel = 0;
|
||||||
@@ -954,6 +955,8 @@ out_fill_res:
|
|||||||
res->type = fa->fa_type;
|
res->type = fa->fa_type;
|
||||||
res->scope = fa->fa_scope;
|
res->scope = fa->fa_scope;
|
||||||
res->fi = fa->fa_info;
|
res->fi = fa->fa_info;
|
||||||
|
res->table = tb;
|
||||||
|
res->fa_head = head;
|
||||||
if (!(fib_flags & FIB_LOOKUP_NOREF))
|
if (!(fib_flags & FIB_LOOKUP_NOREF))
|
||||||
atomic_inc(&res->fi->fib_clntref);
|
atomic_inc(&res->fi->fib_clntref);
|
||||||
return 0;
|
return 0;
|
||||||
|
@@ -1340,7 +1340,7 @@ err:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* should be called with rcu_read_lock */
|
/* 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,
|
t_key key, const struct flowi *flp,
|
||||||
struct fib_result *res, int fib_flags)
|
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)))
|
if (l->key != (key & ntohl(mask)))
|
||||||
continue;
|
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
|
#ifdef CONFIG_IP_FIB_TRIE_STATS
|
||||||
if (err <= 0)
|
if (err <= 0)
|
||||||
@@ -1398,7 +1398,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi *flp,
|
|||||||
|
|
||||||
/* Just a leaf? */
|
/* Just a leaf? */
|
||||||
if (IS_LEAF(n)) {
|
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;
|
goto found;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1423,7 +1423,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi *flp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (IS_LEAF(n)) {
|
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)
|
if (ret > 0)
|
||||||
goto backtrace;
|
goto backtrace;
|
||||||
goto found;
|
goto found;
|
||||||
|
Reference in New Issue
Block a user