svn commit: r196671 - in stable/8/sys: . amd64/include/xen
cddl/contrib/opensolaris contrib/dev/acpica contrib/pf
dev/xen/xenpci netinet6
Qing Li
qingli at FreeBSD.org
Sun Aug 30 22:36:47 UTC 2009
Author: qingli
Date: Sun Aug 30 22:36:46 2009
New Revision: 196671
URL: http://svn.freebsd.org/changeset/base/196671
Log:
MFC r196569
When multiple interfaces exist in the system, with each interface having
an IPv6 address assigned to it, and if an incoming packet received on
one interface has a packet destination address that belongs to another
interface, the routing table is consulted to determine how to reach this
packet destination. Since the packet destination is an interface address,
the route table will return a host route with the loopback interface as
rt_ifp. The input code must recognize this fact, instead of using the
loopback interface, the input code performs a search to find the right
interface that owns the given IPv6 address.
Reviewed by: bz, gnn, kmacy
Approved by: re
Modified:
stable/8/sys/ (props changed)
stable/8/sys/amd64/include/xen/ (props changed)
stable/8/sys/cddl/contrib/opensolaris/ (props changed)
stable/8/sys/contrib/dev/acpica/ (props changed)
stable/8/sys/contrib/pf/ (props changed)
stable/8/sys/dev/xen/xenpci/ (props changed)
stable/8/sys/netinet6/ip6_input.c
Modified: stable/8/sys/netinet6/ip6_input.c
==============================================================================
--- stable/8/sys/netinet6/ip6_input.c Sun Aug 30 22:35:20 2009 (r196670)
+++ stable/8/sys/netinet6/ip6_input.c Sun Aug 30 22:36:46 2009 (r196671)
@@ -628,8 +628,27 @@ passin:
&rt6_key(rin6.ro_rt)->sin6_addr)
#endif
rin6.ro_rt->rt_ifp->if_type == IFT_LOOP) {
- struct in6_ifaddr *ia6 =
- (struct in6_ifaddr *)rin6.ro_rt->rt_ifa;
+ int free_ia6 = 0;
+ struct in6_ifaddr *ia6;
+
+ /*
+ * found the loopback route to the interface address
+ */
+ if (rin6.ro_rt->rt_gateway->sa_family == AF_LINK) {
+ struct sockaddr_in6 dest6;
+
+ bzero(&dest6, sizeof(dest6));
+ dest6.sin6_family = AF_INET6;
+ dest6.sin6_len = sizeof(dest6);
+ dest6.sin6_addr = ip6->ip6_dst;
+ ia6 = (struct in6_ifaddr *)
+ ifa_ifwithaddr((struct sockaddr *)&dest6);
+ if (ia6 == NULL)
+ goto bad;
+ free_ia6 = 1;
+ }
+ else
+ ia6 = (struct in6_ifaddr *)rin6.ro_rt->rt_ifa;
/*
* record address information into m_tag.
@@ -647,6 +666,8 @@ passin:
/* Count the packet in the ip address stats */
ia6->ia_ifa.if_ipackets++;
ia6->ia_ifa.if_ibytes += m->m_pkthdr.len;
+ if (ia6 != NULL && free_ia6 != 0)
+ ifa_free(&ia6->ia_ifa);
goto hbhcheck;
} else {
char ip6bufs[INET6_ADDRSTRLEN];
@@ -657,6 +678,8 @@ passin:
ip6_sprintf(ip6bufs, &ip6->ip6_src),
ip6_sprintf(ip6bufd, &ip6->ip6_dst)));
+ if (ia6 != NULL && free_ia6 != 0)
+ ifa_free(&ia6->ia_ifa);
goto bad;
}
}
More information about the svn-src-all
mailing list