Leaving out the source address from routing cache entries when using routing subtrees causes all kinds of problems. Make sure this doesn't happen.
Signed-off-by: Ville Nuorvala <[EMAIL PROTECTED]> --- net/ipv6/route.c | 31 +++++++++++++++++-------------- 1 files changed, 17 insertions(+), 14 deletions(-) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 7cd7747..7c3438e 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -594,29 +594,28 @@ static struct rt6_info *rt6_alloc_cow(st ipv6_addr_copy(&rt->rt6i_dst.addr, daddr); rt->rt6i_dst.plen = 128; - rt->rt6i_flags |= RTF_CACHE; - rt->u.dst.flags |= DST_HOST; - #ifdef CONFIG_IPV6_SUBTREES - if (rt->rt6i_src.plen && saddr) { - ipv6_addr_copy(&rt->rt6i_src.addr, saddr); - rt->rt6i_src.plen = 128; - } + ipv6_addr_copy(&rt->rt6i_src.addr, saddr); + rt->rt6i_src.plen = 128; #endif - + rt->rt6i_flags |= RTF_CACHE; + rt->u.dst.flags |= DST_HOST; rt->rt6i_nexthop = ndisc_get_neigh(rt->rt6i_dev, &rt->rt6i_gateway); - } return rt; } -static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, struct in6_addr *daddr) +static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, struct in6_addr *daddr, struct in6_addr *saddr) { struct rt6_info *rt = ip6_rt_copy(ort); if (rt) { ipv6_addr_copy(&rt->rt6i_dst.addr, daddr); rt->rt6i_dst.plen = 128; +#ifdef CONFIG_IPV6_SUBTREES + ipv6_addr_copy(&rt->rt6i_src.addr, saddr); + rt->rt6i_src.plen = 128; +#endif rt->rt6i_flags |= RTF_CACHE; rt->u.dst.flags |= DST_HOST; rt->rt6i_nexthop = neigh_clone(ort->rt6i_nexthop); @@ -654,7 +653,7 @@ restart: nrt = rt6_alloc_cow(rt, &fl->fl6_dst, &fl->fl6_src); else { #if CLONE_OFFLINK_ROUTE - nrt = rt6_alloc_clone(rt, &fl->fl6_dst); + nrt = rt6_alloc_clone(rt, &fl->fl6_dst, &fl->fl6_src); #else goto out2; #endif @@ -756,10 +755,10 @@ restart: ipv6_addr_copy(&fl->fl6_src, &saddr); } if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP)) - nrt = rt6_alloc_cow(rt, &fl->fl6_dst, &fl->fl6_src); + nrt = rt6_alloc_cow(rt, &fl->fl6_dst, &saddr); else { #if CLONE_OFFLINK_ROUTE - nrt = rt6_alloc_clone(rt, &fl->fl6_dst); + nrt = rt6_alloc_clone(rt, &fl->fl6_dst, &saddr); #else goto out2; #endif @@ -1429,6 +1428,10 @@ void rt6_redirect(struct in6_addr *dest, ipv6_addr_copy(&nrt->rt6i_dst.addr, dest); nrt->rt6i_dst.plen = 128; +#ifdef CONFIG_IPV6_SUBTREES + ipv6_addr_copy(&nrt->rt6i_src.addr, src); + nrt->rt6i_src.plen = 128; +#endif nrt->u.dst.flags |= DST_HOST; ipv6_addr_copy(&nrt->rt6i_gateway, (struct in6_addr*)neigh->primary_key); @@ -1511,7 +1514,7 @@ void rt6_pmtu_discovery(struct in6_addr if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP)) nrt = rt6_alloc_cow(rt, daddr, saddr); else - nrt = rt6_alloc_clone(rt, daddr); + nrt = rt6_alloc_clone(rt, daddr, saddr); if (nrt) { nrt->u.dst.metrics[RTAX_MTU-1] = pmtu; -- 1.4.2.3 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html