]> git.hungrycats.org Git - linux/commitdiff
[IPV4]: Do fib_alias lookup walk directly in fib_semantic_match().
authorDavid S. Miller <davem@nuts.davemloft.net>
Tue, 28 Sep 2004 14:23:40 +0000 (07:23 -0700)
committerDavid S. Miller <davem@nuts.davemloft.net>
Tue, 28 Sep 2004 14:23:40 +0000 (07:23 -0700)
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/fib_hash.c
net/ipv4/fib_lookup.h
net/ipv4/fib_semantics.c

index f53995dccf9da85758cc17e35ec16c9d97ea6d64..8aa5b76f465377bb917d74212fdc0352b440d2d9 100644 (file)
@@ -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)];
                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;
index b93561cfaf8710d6609cc58ead772b66033a9714..d504a28ce78c03c2b6024d8e4092cde9233c6f02 100644 (file)
@@ -17,8 +17,9 @@ struct fib_alias {
 #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,
index 9c01c6487ef51f9a217b0af9b23446882a5dfb0f..e2a772d3bc4cc27cf07bd6b7ac7fe2a1822a53fb 100644 (file)
@@ -760,51 +760,73 @@ failure:
        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;
+       list_for_each_entry(fa, head, fa_list) {
+               int err;
 
-               res->fi = fi;
+               if (fa->fa_tos &&
+                   fa->fa_tos != flp->fl4_tos)
+                       continue;
 
-               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;
-                       }
+               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 */