Commit cb6b9085 authored by David S. Miller's avatar David S. Miller

[IPV4]: Do fib_alias lookup walk directly in fib_semantic_match().

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c6ccac36
...@@ -256,32 +256,14 @@ fn_hash_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result ...@@ -256,32 +256,14 @@ fn_hash_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result
head = &fz->fz_hash[fn_hash(k, fz)]; head = &fz->fz_hash[fn_hash(k, fz)];
hlist_for_each_entry(f, node, head, fn_hash) { hlist_for_each_entry(f, node, head, fn_hash) {
struct fib_alias *fa;
if (f->fn_key != k) if (f->fn_key != k)
continue; continue;
list_for_each_entry(fa, &f->fn_alias, fa_list) { err = fib_semantic_match(&f->fn_alias,
if (fa->fa_tos && flp, res,
fa->fa_tos != flp->fl4_tos) fz->fz_order);
continue; if (err <= 0)
if (fa->fa_scope < flp->fl4_scope) goto out;
continue;
fa->fa_state |= FA_S_ACCESSED;
err = fib_semantic_match(fa->fa_type,
fa->fa_info,
flp, res);
if (err == 0) {
res->type = fa->fa_type;
res->scope = fa->fa_scope;
res->prefixlen = fz->fz_order;
goto out;
}
if (err < 0)
goto out;
}
} }
} }
err = 1; err = 1;
......
...@@ -17,8 +17,9 @@ struct fib_alias { ...@@ -17,8 +17,9 @@ struct fib_alias {
#define FA_S_ACCESSED 0x01 #define FA_S_ACCESSED 0x01
/* Exported by fib_semantics.c */ /* Exported by fib_semantics.c */
extern int fib_semantic_match(int type, struct fib_info *, extern int fib_semantic_match(struct list_head *head,
const struct flowi *, struct fib_result *); const struct flowi *flp,
struct fib_result *res, int prefixlen);
extern void fib_release_info(struct fib_info *); extern void fib_release_info(struct fib_info *);
extern struct fib_info *fib_create_info(const struct rtmsg *r, extern struct fib_info *fib_create_info(const struct rtmsg *r,
struct kern_rta *rta, struct kern_rta *rta,
......
...@@ -760,51 +760,73 @@ fib_create_info(const struct rtmsg *r, struct kern_rta *rta, ...@@ -760,51 +760,73 @@ fib_create_info(const struct rtmsg *r, struct kern_rta *rta,
return NULL; return NULL;
} }
int int fib_semantic_match(struct list_head *head, const struct flowi *flp,
fib_semantic_match(int type, struct fib_info *fi, const struct flowi *flp, struct fib_result *res) struct fib_result *res, int prefixlen)
{ {
int err = fib_props[type].error; struct fib_alias *fa;
int nh_sel = 0;
if (err == 0) { list_for_each_entry(fa, head, fa_list) {
if (fi->fib_flags&RTNH_F_DEAD) int err;
return 1;
res->fi = fi; if (fa->fa_tos &&
fa->fa_tos != flp->fl4_tos)
continue;
switch (type) { if (fa->fa_scope < flp->fl4_scope)
case RTN_UNICAST: continue;
case RTN_LOCAL:
case RTN_BROADCAST: fa->fa_state |= FA_S_ACCESSED;
case RTN_ANYCAST:
case RTN_MULTICAST: err = fib_props[fa->fa_type].error;
for_nexthops(fi) { if (err == 0) {
if (nh->nh_flags&RTNH_F_DEAD) struct fib_info *fi = fa->fa_info;
continue;
if (!flp->oif || flp->oif == nh->nh_oif) if (fi->fib_flags & RTNH_F_DEAD)
break; continue;
}
switch (fa->fa_type) {
case RTN_UNICAST:
case RTN_LOCAL:
case RTN_BROADCAST:
case RTN_ANYCAST:
case RTN_MULTICAST:
for_nexthops(fi) {
if (nh->nh_flags&RTNH_F_DEAD)
continue;
if (!flp->oif || flp->oif == nh->nh_oif)
break;
}
#ifdef CONFIG_IP_ROUTE_MULTIPATH #ifdef CONFIG_IP_ROUTE_MULTIPATH
if (nhsel < fi->fib_nhs) { if (nhsel < fi->fib_nhs) {
res->nh_sel = nhsel; nh_sel = nhsel;
atomic_inc(&fi->fib_clntref); goto out_fill_res;
return 0; }
}
#else #else
if (nhsel < 1) { if (nhsel < 1) {
atomic_inc(&fi->fib_clntref); goto out_fill_res;
return 0; }
}
#endif #endif
endfor_nexthops(fi); endfor_nexthops(fi);
res->fi = NULL; continue;
return 1;
default: default:
res->fi = NULL; printk(KERN_DEBUG "impossible 102\n");
printk(KERN_DEBUG "impossible 102\n"); return -EINVAL;
return -EINVAL; };
} }
return err;
} }
return err; return 1;
out_fill_res:
res->prefixlen = prefixlen;
res->nh_sel = nh_sel;
res->type = fa->fa_type;
res->scope = fa->fa_scope;
res->fi = fa->fa_info;
atomic_inc(&res->fi->fib_clntref);
return 0;
} }
/* Find appropriate source address to this destination */ /* Find appropriate source address to this destination */
......
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