Hi, From: Markus Stumpf <[EMAIL PROTECTED]>
> I am trying to get dnscache running with IPv6 patches. > dnscache binds to the IPv6 unqualified address "::". This works fine > and I get (from netstat) > udp46 0 0 *.53 *.* > As the sending address the IPv6 unqualified address "::" is used, also. > > As long as I only send queries via either IPv6 or IPv4 all works well, but > all subsequent queries via IPv6 after one or more queries via > IPv4 fail. The queries arrive properly, but sending the answer fails. > > >From truss I can see for that IPv6 answers: > sendto(0x3,0x80f34e0,0x55,0x0,0xbfbffbd0,0x1c) ERR#65 'No route to host' > for all queries via IPv6, queries via IPv4 still work without problems. > It doesn't matter if I use different source hosts for the queries via IPv6, > it fails for all of them. This is a cached route problem. struct inpcb has a route entry for cached route. Since inpcb is shared by both IPv4 and IPv6, the cached route entry is also shared by them. 4.5-STABLE doesn't check the protocol family of the cached route when using it. Therefore, once a IPv4 route is cached, ip6_output mistakingly use it as a cached route for IPv6 destination. Please try attached patches. --- Keiichi SHIMA IIJ Research Laboratory <[EMAIL PROTECTED]> KAME Project <[EMAIL PROTECTED]>
--- ip_output.c.orig Wed Mar 27 14:29:43 2002 +++ ip_output.c Wed Mar 27 13:54:40 2002 @@ -219,6 +219,7 @@ * and is still up. If not, free it and try again. */ if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 || + dst->sin_family != AF_INET || dst->sin_addr.s_addr != ip->ip_dst.s_addr)) { RTFREE(ro->ro_rt); ro->ro_rt = (struct rtentry *)0;
--- ip6_output.c.orig Wed Mar 27 14:23:54 2002 +++ ip6_output.c Wed Mar 27 14:08:22 2002 @@ -461,6 +461,7 @@ * and is still up. If not, free it and try again. */ if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 || + dst->sin6_family != AF_INET6 || !IN6_ARE_ADDR_EQUAL(&dst->sin6_addr, &ip6->ip6_dst))) { RTFREE(ro->ro_rt); ro->ro_rt = (struct rtentry *)0;
--- in6_src.c.orig Wed Mar 27 14:24:28 2002 +++ in6_src.c Wed Mar 27 14:47:31 2002 @@ -239,7 +239,9 @@ */ if (ro) { if (ro->ro_rt && - !IN6_ARE_ADDR_EQUAL(&satosin6(&ro->ro_dst)->sin6_addr, dst)) { + (!(ro->ro_rt->rt_flags & RTF_UP) || + ro->ro_dst.sin6_family != AF_INET6 || + !IN6_ARE_ADDR_EQUAL(&satosin6(&ro->ro_dst)->sin6_addr, dst))) { RTFREE(ro->ro_rt); ro->ro_rt = (struct rtentry *)0; }