Commit 5786ec60 authored by Alexander Duyck's avatar Alexander Duyck Committed by David S. Miller

fib_trie: Replace plen with slen in leaf_info

This replaces the prefix length variable in the leaf_info structure with a
suffix length value, or host identifier length in bits.  By doing this it
makes it easier to sort out since the tnodes and leaf are carrying this
value as well since it is compatible with the ->pos field in tnodes.

I also cleaned up one spot that had some list manipulation that could be
simplified.  I basically updated it so that we just use hlist_add_head_rcu
instead of calling hlist_add_before_rcu on the first node in the list.
Signed-off-by: default avatarAlexander Duyck <alexander.h.duyck@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 56315f9e
...@@ -114,8 +114,7 @@ struct tnode { ...@@ -114,8 +114,7 @@ struct tnode {
struct leaf_info { struct leaf_info {
struct hlist_node hlist; struct hlist_node hlist;
int plen; unsigned char slen;
u32 mask_plen; /* ntohl(inet_make_mask(plen)) */
struct hlist_head falh; struct hlist_head falh;
struct rcu_head rcu; struct rcu_head rcu;
}; };
...@@ -337,8 +336,7 @@ static struct leaf_info *leaf_info_new(int plen) ...@@ -337,8 +336,7 @@ static struct leaf_info *leaf_info_new(int plen)
{ {
struct leaf_info *li = kmalloc(sizeof(struct leaf_info), GFP_KERNEL); struct leaf_info *li = kmalloc(sizeof(struct leaf_info), GFP_KERNEL);
if (li) { if (li) {
li->plen = plen; li->slen = KEYLENGTH - plen;
li->mask_plen = ntohl(inet_make_mask(plen));
INIT_HLIST_HEAD(&li->falh); INIT_HLIST_HEAD(&li->falh);
} }
return li; return li;
...@@ -873,9 +871,10 @@ static struct leaf_info *find_leaf_info(struct tnode *l, int plen) ...@@ -873,9 +871,10 @@ static struct leaf_info *find_leaf_info(struct tnode *l, int plen)
{ {
struct hlist_head *head = &l->list; struct hlist_head *head = &l->list;
struct leaf_info *li; struct leaf_info *li;
int slen = KEYLENGTH - plen;
hlist_for_each_entry_rcu(li, head, hlist) hlist_for_each_entry_rcu(li, head, hlist)
if (li->plen == plen) if (li->slen == slen)
return li; return li;
return NULL; return NULL;
...@@ -929,33 +928,29 @@ static void remove_leaf_info(struct tnode *l, struct leaf_info *old) ...@@ -929,33 +928,29 @@ static void remove_leaf_info(struct tnode *l, struct leaf_info *old)
return; return;
/* update the trie with the latest suffix length */ /* update the trie with the latest suffix length */
l->slen = KEYLENGTH - li->plen; l->slen = li->slen;
leaf_pull_suffix(l); leaf_pull_suffix(l);
} }
static void insert_leaf_info(struct tnode *l, struct leaf_info *new) static void insert_leaf_info(struct tnode *l, struct leaf_info *new)
{ {
struct hlist_head *head = &l->list; struct hlist_head *head = &l->list;
struct leaf_info *li = NULL, *last = NULL; struct leaf_info *li, *last = NULL;
if (hlist_empty(head)) {
hlist_add_head_rcu(&new->hlist, head);
} else {
hlist_for_each_entry(li, head, hlist) {
if (new->plen > li->plen)
break;
last = li; hlist_for_each_entry(li, head, hlist) {
} if (new->slen < li->slen)
if (last) break;
hlist_add_behind_rcu(&new->hlist, &last->hlist); last = li;
else
hlist_add_before_rcu(&new->hlist, &li->hlist);
} }
if (last)
hlist_add_behind_rcu(&new->hlist, &last->hlist);
else
hlist_add_head_rcu(&new->hlist, head);
/* if we added to the tail node then we need to update slen */ /* if we added to the tail node then we need to update slen */
if (l->slen < (KEYLENGTH - new->plen)) { if (l->slen < new->slen) {
l->slen = KEYLENGTH - new->plen; l->slen = new->slen;
leaf_push_suffix(l); leaf_push_suffix(l);
} }
} }
...@@ -1139,7 +1134,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) ...@@ -1139,7 +1134,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
int err; int err;
struct tnode *l; struct tnode *l;
if (plen > 32) if (plen > KEYLENGTH)
return -EINVAL; return -EINVAL;
key = ntohl(cfg->fc_dst); key = ntohl(cfg->fc_dst);
...@@ -1425,7 +1420,8 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp, ...@@ -1425,7 +1420,8 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp,
hlist_for_each_entry_rcu(li, &n->list, hlist) { hlist_for_each_entry_rcu(li, &n->list, hlist) {
struct fib_alias *fa; struct fib_alias *fa;
if ((key ^ n->key) & li->mask_plen) if (((key ^ n->key) >= (1ul << li->slen)) &&
((BITS_PER_LONG > KEYLENGTH) || (li->slen != KEYLENGTH)))
continue; continue;
hlist_for_each_entry_rcu(fa, &li->falh, fa_list) { hlist_for_each_entry_rcu(fa, &li->falh, fa_list) {
...@@ -1459,7 +1455,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp, ...@@ -1459,7 +1455,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp,
if (!(fib_flags & FIB_LOOKUP_NOREF)) if (!(fib_flags & FIB_LOOKUP_NOREF))
atomic_inc(&fi->fib_clntref); atomic_inc(&fi->fib_clntref);
res->prefixlen = li->plen; res->prefixlen = KEYLENGTH - li->slen;
res->nh_sel = nhsel; res->nh_sel = nhsel;
res->type = fa->fa_type; res->type = fa->fa_type;
res->scope = fi->fib_scope; res->scope = fi->fib_scope;
...@@ -1614,7 +1610,7 @@ static int trie_flush_leaf(struct tnode *l) ...@@ -1614,7 +1610,7 @@ static int trie_flush_leaf(struct tnode *l)
int found = 0; int found = 0;
struct hlist_node *tmp; struct hlist_node *tmp;
struct leaf_info *li; struct leaf_info *li;
unsigned char plen = KEYLENGTH; unsigned char slen = 0;
hlist_for_each_entry_safe(li, tmp, &l->list, hlist) { hlist_for_each_entry_safe(li, tmp, &l->list, hlist) {
found += trie_flush_list(&li->falh); found += trie_flush_list(&li->falh);
...@@ -1625,10 +1621,10 @@ static int trie_flush_leaf(struct tnode *l) ...@@ -1625,10 +1621,10 @@ static int trie_flush_leaf(struct tnode *l)
continue; continue;
} }
plen = li->plen; slen = li->slen;
} }
l->slen = KEYLENGTH - plen; l->slen = slen;
return found; return found;
} }
...@@ -1739,7 +1735,7 @@ void fib_free_table(struct fib_table *tb) ...@@ -1739,7 +1735,7 @@ void fib_free_table(struct fib_table *tb)
kfree(tb); kfree(tb);
} }
static int fn_trie_dump_fa(t_key key, int plen, struct hlist_head *fah, static int fn_trie_dump_fa(t_key key, int slen, struct hlist_head *fah,
struct fib_table *tb, struct fib_table *tb,
struct sk_buff *skb, struct netlink_callback *cb) struct sk_buff *skb, struct netlink_callback *cb)
{ {
...@@ -1764,7 +1760,7 @@ static int fn_trie_dump_fa(t_key key, int plen, struct hlist_head *fah, ...@@ -1764,7 +1760,7 @@ static int fn_trie_dump_fa(t_key key, int plen, struct hlist_head *fah,
tb->tb_id, tb->tb_id,
fa->fa_type, fa->fa_type,
xkey, xkey,
plen, KEYLENGTH - slen,
fa->fa_tos, fa->fa_tos,
fa->fa_info, NLM_F_MULTI) < 0) { fa->fa_info, NLM_F_MULTI) < 0) {
cb->args[5] = i; cb->args[5] = i;
...@@ -1798,7 +1794,7 @@ static int fn_trie_dump_leaf(struct tnode *l, struct fib_table *tb, ...@@ -1798,7 +1794,7 @@ static int fn_trie_dump_leaf(struct tnode *l, struct fib_table *tb,
if (hlist_empty(&li->falh)) if (hlist_empty(&li->falh))
continue; continue;
if (fn_trie_dump_fa(l->key, li->plen, &li->falh, tb, skb, cb) < 0) { if (fn_trie_dump_fa(l->key, li->slen, &li->falh, tb, skb, cb) < 0) {
cb->args[4] = i; cb->args[4] = i;
return -1; return -1;
} }
...@@ -2284,7 +2280,8 @@ static int fib_trie_seq_show(struct seq_file *seq, void *v) ...@@ -2284,7 +2280,8 @@ static int fib_trie_seq_show(struct seq_file *seq, void *v)
char buf1[32], buf2[32]; char buf1[32], buf2[32];
seq_indent(seq, iter->depth+1); seq_indent(seq, iter->depth+1);
seq_printf(seq, " /%d %s %s", li->plen, seq_printf(seq, " /%zu %s %s",
KEYLENGTH - li->slen,
rtn_scope(buf1, sizeof(buf1), rtn_scope(buf1, sizeof(buf1),
fa->fa_info->fib_scope), fa->fa_info->fib_scope),
rtn_type(buf2, sizeof(buf2), rtn_type(buf2, sizeof(buf2),
...@@ -2434,7 +2431,7 @@ static int fib_route_seq_show(struct seq_file *seq, void *v) ...@@ -2434,7 +2431,7 @@ static int fib_route_seq_show(struct seq_file *seq, void *v)
struct fib_alias *fa; struct fib_alias *fa;
__be32 mask, prefix; __be32 mask, prefix;
mask = inet_make_mask(li->plen); mask = inet_make_mask(KEYLENGTH - li->slen);
prefix = htonl(l->key); prefix = htonl(l->key);
hlist_for_each_entry_rcu(fa, &li->falh, fa_list) { hlist_for_each_entry_rcu(fa, &li->falh, fa_list) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment