make sure to check address family on route cache. with IPv4 mapped
address we can see both AF_INET/INET6.
This commit is contained in:
parent
d1f5dc17b6
commit
ae1b9c29e9
sys
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: in_pcb.c,v 1.73 2001/11/13 00:32:36 lukem Exp $ */
|
||||
/* $NetBSD: in_pcb.c,v 1.74 2002/01/22 03:53:55 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -102,7 +102,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: in_pcb.c,v 1.73 2001/11/13 00:32:36 lukem Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: in_pcb.c,v 1.74 2002/01/22 03:53:55 itojun Exp $");
|
||||
|
||||
#include "opt_ipsec.h"
|
||||
|
||||
@ -397,78 +397,6 @@ in_pcbconnect(v, nam)
|
||||
* destinations.
|
||||
*/
|
||||
if (in_nullhost(inp->inp_laddr)) {
|
||||
#if 0
|
||||
struct route *ro;
|
||||
|
||||
ia = (struct in_ifaddr *)0;
|
||||
/*
|
||||
* If route is known or can be allocated now,
|
||||
* our src addr is taken from the i/f, else punt.
|
||||
*/
|
||||
ro = &inp->inp_route;
|
||||
if (ro->ro_rt &&
|
||||
(!in_hosteq(satosin(&ro->ro_dst)->sin_addr,
|
||||
sin->sin_addr) ||
|
||||
inp->inp_socket->so_options & SO_DONTROUTE)) {
|
||||
RTFREE(ro->ro_rt);
|
||||
ro->ro_rt = (struct rtentry *)0;
|
||||
}
|
||||
if ((inp->inp_socket->so_options & SO_DONTROUTE) == 0 && /*XXX*/
|
||||
(ro->ro_rt == (struct rtentry *)0 ||
|
||||
ro->ro_rt->rt_ifp == (struct ifnet *)0)) {
|
||||
/* No route yet, so try to acquire one */
|
||||
ro->ro_dst.sa_family = AF_INET;
|
||||
ro->ro_dst.sa_len = sizeof(struct sockaddr_in);
|
||||
satosin(&ro->ro_dst)->sin_addr = sin->sin_addr;
|
||||
rtalloc(ro);
|
||||
}
|
||||
/*
|
||||
* If we found a route, use the address
|
||||
* corresponding to the outgoing interface
|
||||
* unless it is the loopback (in case a route
|
||||
* to our address on another net goes to loopback).
|
||||
*
|
||||
* XXX Is this still true? Do we care?
|
||||
*/
|
||||
if (ro->ro_rt && !(ro->ro_rt->rt_ifp->if_flags & IFF_LOOPBACK))
|
||||
ia = ifatoia(ro->ro_rt->rt_ifa);
|
||||
if (ia == NULL) {
|
||||
u_int16_t fport = sin->sin_port;
|
||||
|
||||
sin->sin_port = 0;
|
||||
ia = ifatoia(ifa_ifwithladdr(sintosa(sin)));
|
||||
sin->sin_port = fport;
|
||||
if (ia == 0) {
|
||||
/* Find 1st non-loopback AF_INET address */
|
||||
TAILQ_FOREACH(ia, &in_ifaddr, ia_list) {
|
||||
if ((ia->ia_ifp->if_flags &
|
||||
IFF_LOOPBACK) == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ia == NULL)
|
||||
return (EADDRNOTAVAIL);
|
||||
}
|
||||
/*
|
||||
* If the destination address is multicast and an outgoing
|
||||
* interface has been set as a multicast option, use the
|
||||
* address of that interface as our source address.
|
||||
*/
|
||||
if (IN_MULTICAST(sin->sin_addr.s_addr) &&
|
||||
inp->inp_moptions != NULL) {
|
||||
struct ip_moptions *imo;
|
||||
struct ifnet *ifp;
|
||||
|
||||
imo = inp->inp_moptions;
|
||||
if (imo->imo_multicast_ifp != NULL) {
|
||||
ifp = imo->imo_multicast_ifp;
|
||||
IFP_TO_IA(ifp, ia); /* XXX */
|
||||
if (ia == 0)
|
||||
return (EADDRNOTAVAIL);
|
||||
}
|
||||
}
|
||||
ifaddr = satosin(&ia->ia_addr);
|
||||
#else
|
||||
int error;
|
||||
ifaddr = in_selectsrc(sin, &inp->inp_route,
|
||||
inp->inp_socket->so_options, inp->inp_moptions, &error);
|
||||
@ -477,7 +405,6 @@ in_pcbconnect(v, nam)
|
||||
error = EADDRNOTAVAIL;
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (in_pcblookup_connect(inp->inp_table, sin->sin_addr, sin->sin_port,
|
||||
!in_nullhost(inp->inp_laddr) ? inp->inp_laddr : ifaddr->sin_addr,
|
||||
@ -911,6 +838,7 @@ in_pcbrtentry(inp)
|
||||
* No route yet, so try to acquire one.
|
||||
*/
|
||||
if (!in_nullhost(inp->inp_faddr)) {
|
||||
bzero(&ro->ro_dst, sizeof(struct sockaddr_in));
|
||||
ro->ro_dst.sa_family = AF_INET;
|
||||
ro->ro_dst.sa_len = sizeof(ro->ro_dst);
|
||||
satosin(&ro->ro_dst)->sin_addr = inp->inp_faddr;
|
||||
@ -934,17 +862,21 @@ in_selectsrc(sin, ro, soopts, mopts, errorp)
|
||||
/*
|
||||
* If route is known or can be allocated now,
|
||||
* our src addr is taken from the i/f, else punt.
|
||||
* Note that we should check the address family of the cached
|
||||
* destination, in case of sharing the cache with IPv6.
|
||||
*/
|
||||
if (ro->ro_rt &&
|
||||
(!in_hosteq(satosin(&ro->ro_dst)->sin_addr, sin->sin_addr) ||
|
||||
(ro->ro_dst.sa_family != AF_INET ||
|
||||
!in_hosteq(satosin(&ro->ro_dst)->sin_addr, sin->sin_addr) ||
|
||||
soopts & SO_DONTROUTE)) {
|
||||
RTFREE(ro->ro_rt);
|
||||
ro->ro_rt = (struct rtentry *)0;
|
||||
}
|
||||
if ((soopts & SO_DONTROUTE) == 0 && /*XXX*/
|
||||
(ro->ro_rt == (struct rtentry *)0 ||
|
||||
ro->ro_rt->rt_ifp == (struct ifnet *)0)) {
|
||||
ro->ro_rt->rt_ifp == (struct ifnet *)0)) {
|
||||
/* No route yet, so try to acquire one */
|
||||
bzero(&ro->ro_dst, sizeof(struct sockaddr_in));
|
||||
ro->ro_dst.sa_family = AF_INET;
|
||||
ro->ro_dst.sa_len = sizeof(struct sockaddr_in);
|
||||
satosin(&ro->ro_dst)->sin_addr = sin->sin_addr;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ip_output.c,v 1.91 2002/01/08 10:05:13 itojun Exp $ */
|
||||
/* $NetBSD: ip_output.c,v 1.92 2002/01/22 03:53:55 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
@ -102,7 +102,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.91 2002/01/08 10:05:13 itojun Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.92 2002/01/22 03:53:55 itojun Exp $");
|
||||
|
||||
#include "opt_pfil_hooks.h"
|
||||
#include "opt_ipsec.h"
|
||||
@ -235,13 +235,17 @@ ip_output(m0, va_alist)
|
||||
* If there is a cached route,
|
||||
* check that it is to the same destination
|
||||
* and is still up. If not, free it and try again.
|
||||
* The address family should also be checked in case of sharing the
|
||||
* cache with IPv6.
|
||||
*/
|
||||
if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 ||
|
||||
dst->sin_family != AF_INET ||
|
||||
!in_hosteq(dst->sin_addr, ip->ip_dst))) {
|
||||
RTFREE(ro->ro_rt);
|
||||
ro->ro_rt = (struct rtentry *)0;
|
||||
}
|
||||
if (ro->ro_rt == 0) {
|
||||
bzero(dst, sizeof(*dst));
|
||||
dst->sin_family = AF_INET;
|
||||
dst->sin_len = sizeof(*dst);
|
||||
dst->sin_addr = ip->ip_dst;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: in6_src.c,v 1.9 2001/11/13 00:57:00 lukem Exp $ */
|
||||
/* $NetBSD: in6_src.c,v 1.10 2002/01/22 03:53:56 itojun Exp $ */
|
||||
/* $KAME: in6_src.c,v 1.36 2001/02/06 04:08:17 itojun Exp $ */
|
||||
|
||||
/*
|
||||
@ -66,7 +66,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: in6_src.c,v 1.9 2001/11/13 00:57:00 lukem Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: in6_src.c,v 1.10 2002/01/22 03:53:56 itojun Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
|
||||
@ -240,10 +240,13 @@ in6_selectsrc(dstsock, opts, mopts, ro, laddr, errorp)
|
||||
/*
|
||||
* If route is known or can be allocated now,
|
||||
* our src addr is taken from the i/f, else punt.
|
||||
* Note that we should check the address family of the
|
||||
* cached destination, in case of sharing the cache with IPv4.
|
||||
*/
|
||||
if (ro) {
|
||||
if (ro->ro_rt &&
|
||||
!IN6_ARE_ADDR_EQUAL(&satosin6(&ro->ro_dst)->sin6_addr, dst)) {
|
||||
(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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user