aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@redhat.com>2015-02-25 15:31:44 -0800
committerDavid S. Miller <davem@davemloft.net>2015-02-27 16:37:07 -0500
commit9b6ebad5c3a152271c6af19cd44e20001ae72fe8 (patch)
treed2ce2a8d6606e8a7e5bd3e4366ed252e673b4598
parentfib_trie: Replace plen with slen in leaf_info (diff)
downloadlinux-dev-9b6ebad5c3a152271c6af19cd44e20001ae72fe8.tar.xz
linux-dev-9b6ebad5c3a152271c6af19cd44e20001ae72fe8.zip
fib_trie: Add slen to fib alias
Make use of an empty spot in the alias to store the suffix length so that we don't need to pull that information from the leaf_info structure. This patch also makes a slight change to the user statistics. Instead of incrementing semantic_match_miss once per leaf_info miss we now just increment it once per leaf if a match was not found. Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/ipv4/fib_lookup.h1
-rw-r--r--net/ipv4/fib_trie.c37
2 files changed, 19 insertions, 19 deletions
diff --git a/net/ipv4/fib_lookup.h b/net/ipv4/fib_lookup.h
index 3cd444f4e0f6..ae2e6eede46e 100644
--- a/net/ipv4/fib_lookup.h
+++ b/net/ipv4/fib_lookup.h
@@ -11,6 +11,7 @@ struct fib_alias {
u8 fa_tos;
u8 fa_type;
u8 fa_state;
+ u8 fa_slen;
struct rcu_head rcu;
};
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index d28362db51a0..79cd8c029cf4 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -1219,6 +1219,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
new_fa->fa_type = cfg->fc_type;
state = fa->fa_state;
new_fa->fa_state = state & ~FA_S_ACCESSED;
+ new_fa->fa_slen = fa->fa_slen;
hlist_replace_rcu(&fa->fa_list, &new_fa->fa_list);
alias_free_mem_rcu(fa);
@@ -1254,10 +1255,9 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
new_fa->fa_tos = tos;
new_fa->fa_type = cfg->fc_type;
new_fa->fa_state = 0;
- /*
- * Insert new entry to the list.
- */
+ new_fa->fa_slen = KEYLENGTH - plen;
+ /* Insert new entry to the list. */
if (!fa_head) {
fa_head = fib_insert_node(t, key, plen);
if (unlikely(!fa_head)) {
@@ -1420,14 +1420,14 @@ found:
hlist_for_each_entry_rcu(li, &n->list, hlist) {
struct fib_alias *fa;
- if (((key ^ n->key) >= (1ul << li->slen)) &&
- ((BITS_PER_LONG > KEYLENGTH) || (li->slen != KEYLENGTH)))
- continue;
-
hlist_for_each_entry_rcu(fa, &li->falh, fa_list) {
struct fib_info *fi = fa->fa_info;
int nhsel, err;
+ if (((key ^ n->key) >= (1ul << fa->fa_slen)) &&
+ ((BITS_PER_LONG > KEYLENGTH) ||
+ (fa->fa_slen != KEYLENGTH)))
+ continue;
if (fa->fa_tos && fa->fa_tos != flp->flowi4_tos)
continue;
if (fi->fib_dead)
@@ -1455,7 +1455,7 @@ found:
if (!(fib_flags & FIB_LOOKUP_NOREF))
atomic_inc(&fi->fib_clntref);
- res->prefixlen = KEYLENGTH - li->slen;
+ res->prefixlen = KEYLENGTH - fa->fa_slen;
res->nh_sel = nhsel;
res->type = fa->fa_type;
res->scope = fi->fib_scope;
@@ -1468,11 +1468,10 @@ found:
return err;
}
}
-
+ }
#ifdef CONFIG_IP_FIB_TRIE_STATS
- this_cpu_inc(stats->semantic_match_miss);
+ this_cpu_inc(stats->semantic_match_miss);
#endif
- }
goto backtrace;
}
EXPORT_SYMBOL_GPL(fib_table_lookup);
@@ -1735,7 +1734,7 @@ void fib_free_table(struct fib_table *tb)
kfree(tb);
}
-static int fn_trie_dump_fa(t_key key, int slen, struct hlist_head *fah,
+static int fn_trie_dump_fa(t_key key, struct hlist_head *fah,
struct fib_table *tb,
struct sk_buff *skb, struct netlink_callback *cb)
{
@@ -1760,7 +1759,7 @@ static int fn_trie_dump_fa(t_key key, int slen, struct hlist_head *fah,
tb->tb_id,
fa->fa_type,
xkey,
- KEYLENGTH - slen,
+ KEYLENGTH - fa->fa_slen,
fa->fa_tos,
fa->fa_info, NLM_F_MULTI) < 0) {
cb->args[5] = i;
@@ -1794,7 +1793,7 @@ static int fn_trie_dump_leaf(struct tnode *l, struct fib_table *tb,
if (hlist_empty(&li->falh))
continue;
- if (fn_trie_dump_fa(l->key, li->slen, &li->falh, tb, skb, cb) < 0) {
+ if (fn_trie_dump_fa(l->key, &li->falh, tb, skb, cb) < 0) {
cb->args[4] = i;
return -1;
}
@@ -2281,7 +2280,7 @@ static int fib_trie_seq_show(struct seq_file *seq, void *v)
seq_indent(seq, iter->depth+1);
seq_printf(seq, " /%zu %s %s",
- KEYLENGTH - li->slen,
+ KEYLENGTH - fa->fa_slen,
rtn_scope(buf1, sizeof(buf1),
fa->fa_info->fib_scope),
rtn_type(buf2, sizeof(buf2),
@@ -2419,6 +2418,7 @@ static int fib_route_seq_show(struct seq_file *seq, void *v)
{
struct tnode *l = v;
struct leaf_info *li;
+ __be32 prefix;
if (v == SEQ_START_TOKEN) {
seq_printf(seq, "%-127s\n", "Iface\tDestination\tGateway "
@@ -2427,15 +2427,14 @@ static int fib_route_seq_show(struct seq_file *seq, void *v)
return 0;
}
+ prefix = htonl(l->key);
+
hlist_for_each_entry_rcu(li, &l->list, hlist) {
struct fib_alias *fa;
- __be32 mask, prefix;
-
- mask = inet_make_mask(KEYLENGTH - li->slen);
- prefix = htonl(l->key);
hlist_for_each_entry_rcu(fa, &li->falh, fa_list) {
const struct fib_info *fi = fa->fa_info;
+ __be32 mask = inet_make_mask(KEYLENGTH - fa->fa_slen);
unsigned int flags = fib_flag_trans(fa->fa_type, mask, fi);
if (fa->fa_type == RTN_BROADCAST