From: YOSHIFUJI Hideaki Date: Thu, 24 Aug 2006 00:22:39 +0000 (-0700) Subject: [IPV6] ROUTE: Search subtree when backtracking. X-Git-Tag: v2.6.19-rc1~1272^2~194 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=982f56f3a9be4651520c0fdd3d80a5d02e95a178;p=linux-2.6 [IPV6] ROUTE: Search subtree when backtracking. Based on MIPL2 kernel patch. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: Ville Nuorvala Signed-off-by: David S. Miller --- diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 8d00a9d77f..bd4cf175ff 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -481,17 +481,23 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, } #endif -#define BACKTRACK() \ -if (rt == &ip6_null_entry && flags & RT6_F_STRICT) { \ - while ((fn = fn->parent) != NULL) { \ - if (fn->fn_flags & RTN_TL_ROOT) { \ - dst_hold(&rt->u.dst); \ - goto out; \ +#define BACKTRACK(saddr) \ +do { \ + if (rt == &ip6_null_entry) { \ + struct fib6_node *pn; \ + while (fn) { \ + if (fn->fn_flags & RTN_TL_ROOT) \ + goto out; \ + pn = fn->parent; \ + if (FIB6_SUBTREE(pn) && FIB6_SUBTREE(pn) != fn) \ + fn = fib6_lookup(pn->subtree, NULL, saddr); \ + else \ + fn = pn; \ + if (fn->fn_flags & RTN_RTINFO) \ + goto restart; \ } \ - if (fn->fn_flags & RTN_RTINFO) \ - goto restart; \ } \ -} +} while(0) static struct rt6_info *ip6_pol_route_lookup(struct fib6_table *table, struct flowi *fl, int flags) @@ -504,7 +510,7 @@ static struct rt6_info *ip6_pol_route_lookup(struct fib6_table *table, restart: rt = fn->leaf; rt = rt6_device_match(rt, fl->oif, flags & RT6_F_STRICT); - BACKTRACK(); + BACKTRACK(&fl->fl6_src); dst_hold(&rt->u.dst); out: read_unlock_bh(&table->tb6_lock); @@ -638,7 +644,7 @@ restart_2: restart: rt = rt6_select(&fn->leaf, fl->iif, strict | reachable); - BACKTRACK(); + BACKTRACK(&fl->fl6_src); if (rt == &ip6_null_entry || rt->rt6i_flags & RTF_CACHE) goto out; @@ -733,7 +739,7 @@ restart_2: restart: rt = rt6_select(&fn->leaf, fl->oif, strict | reachable); - BACKTRACK(); + BACKTRACK(&fl->fl6_src); if (rt == &ip6_null_entry || rt->rt6i_flags & RTF_CACHE) goto out;