# This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/09/28 21:23:40-07:00 davem@nuts.davemloft.net # [IPV4]: Do fib_alias lookup walk directly in fib_semantic_match(). # # Signed-off-by: David S. Miller # # net/ipv4/fib_semantics.c # 2004/09/28 21:23:07-07:00 davem@nuts.davemloft.net +60 -38 # [IPV4]: Do fib_alias lookup walk directly in fib_semantic_match(). # # net/ipv4/fib_lookup.h # 2004/09/28 21:23:07-07:00 davem@nuts.davemloft.net +3 -2 # [IPV4]: Do fib_alias lookup walk directly in fib_semantic_match(). # # net/ipv4/fib_hash.c # 2004/09/28 21:23:07-07:00 davem@nuts.davemloft.net +5 -23 # [IPV4]: Do fib_alias lookup walk directly in fib_semantic_match(). # diff -Nru a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c --- a/net/ipv4/fib_hash.c 2004-09-28 21:25:20 -07:00 +++ b/net/ipv4/fib_hash.c 2004-09-28 21:25:20 -07:00 @@ -256,32 +256,14 @@ head = &fz->fz_hash[fn_hash(k, fz)]; hlist_for_each_entry(f, node, head, fn_hash) { - struct fib_alias *fa; - if (f->fn_key != k) continue; - list_for_each_entry(fa, &f->fn_alias, fa_list) { - if (fa->fa_tos && - fa->fa_tos != flp->fl4_tos) - continue; - if (fa->fa_scope < flp->fl4_scope) - 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 = fib_semantic_match(&f->fn_alias, + flp, res, + fz->fz_order); + if (err <= 0) + goto out; } } err = 1; diff -Nru a/net/ipv4/fib_lookup.h b/net/ipv4/fib_lookup.h --- a/net/ipv4/fib_lookup.h 2004-09-28 21:25:20 -07:00 +++ b/net/ipv4/fib_lookup.h 2004-09-28 21:25:20 -07:00 @@ -17,8 +17,9 @@ #define FA_S_ACCESSED 0x01 /* Exported by fib_semantics.c */ -extern int fib_semantic_match(int type, struct fib_info *, - const struct flowi *, struct fib_result *); +extern int fib_semantic_match(struct list_head *head, + const struct flowi *flp, + struct fib_result *res, int prefixlen); extern void fib_release_info(struct fib_info *); extern struct fib_info *fib_create_info(const struct rtmsg *r, struct kern_rta *rta, diff -Nru a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c --- a/net/ipv4/fib_semantics.c 2004-09-28 21:25:20 -07:00 +++ b/net/ipv4/fib_semantics.c 2004-09-28 21:25:20 -07:00 @@ -760,51 +760,73 @@ return NULL; } -int -fib_semantic_match(int type, struct fib_info *fi, const struct flowi *flp, struct fib_result *res) +int fib_semantic_match(struct list_head *head, const struct flowi *flp, + struct fib_result *res, int prefixlen) { - int err = fib_props[type].error; + struct fib_alias *fa; + int nh_sel = 0; - if (err == 0) { - if (fi->fib_flags&RTNH_F_DEAD) - return 1; - - res->fi = fi; - - switch (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; - } + list_for_each_entry(fa, head, fa_list) { + int err; + + if (fa->fa_tos && + fa->fa_tos != flp->fl4_tos) + continue; + + if (fa->fa_scope < flp->fl4_scope) + continue; + + fa->fa_state |= FA_S_ACCESSED; + + err = fib_props[fa->fa_type].error; + if (err == 0) { + struct fib_info *fi = fa->fa_info; + + if (fi->fib_flags & RTNH_F_DEAD) + 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 - if (nhsel < fi->fib_nhs) { - res->nh_sel = nhsel; - atomic_inc(&fi->fib_clntref); - return 0; - } + if (nhsel < fi->fib_nhs) { + nh_sel = nhsel; + goto out_fill_res; + } #else - if (nhsel < 1) { - atomic_inc(&fi->fib_clntref); - return 0; - } + if (nhsel < 1) { + goto out_fill_res; + } #endif - endfor_nexthops(fi); - res->fi = NULL; - return 1; - default: - res->fi = NULL; - printk(KERN_DEBUG "impossible 102\n"); - return -EINVAL; + endfor_nexthops(fi); + continue; + + default: + printk(KERN_DEBUG "impossible 102\n"); + 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 */