svn commit: r246754 - user/ae/inet6/sys/netinet6
Andrey V. Elsukov
ae at FreeBSD.org
Wed Feb 13 09:07:38 UTC 2013
Author: ae
Date: Wed Feb 13 09:07:37 2013
New Revision: 246754
URL: http://svnweb.freebsd.org/changeset/base/246754
Log:
Use in6ifa_ifwithaddr function instead of ip6_getdstifaddr. Now they
are equal. Use mbuf's rcvif to determine the zone id of destination
address.
Modified:
user/ae/inet6/sys/netinet6/icmp6.c
Modified: user/ae/inet6/sys/netinet6/icmp6.c
==============================================================================
--- user/ae/inet6/sys/netinet6/icmp6.c Wed Feb 13 08:28:27 2013 (r246753)
+++ user/ae/inet6/sys/netinet6/icmp6.c Wed Feb 13 09:07:37 2013 (r246754)
@@ -1279,6 +1279,7 @@ ni6_input(struct mbuf *m, int off)
int oldfqdn = 0; /* if 1, return pascal string (03 draft) */
char *subj = NULL;
struct in6_ifaddr *ia6 = NULL;
+ uint32_t zoneid;
ip6 = mtod(m, struct ip6_hdr *);
#ifndef PULLDOWN_TEST
@@ -1322,8 +1323,11 @@ ni6_input(struct mbuf *m, int off)
goto bad;
/* else it's a link-local multicast, fine */
} else { /* unicast or anycast */
- if ((ia6 = ip6_getdstifaddr(m)) == NULL)
- goto bad; /* XXX impossible */
+ zoneid = in6_getscopezone(m->m_hdr.rcvif,
+ in6_addrscope(&ip6->ip6_dst));
+ ia6 = in6ifa_ifwithaddr(&ip6->ip6_dst, zoneid);
+ if (ia6 == NULL)
+ goto bad;
if ((ia6->ia6_flags & IN6_IFF_TEMPORARY) &&
!(V_icmp6_nodeinfo & ICMP6_NODEINFO_TMPADDROK)) {
@@ -2157,7 +2161,8 @@ icmp6_reflect(struct mbuf *m, size_t off
int plen;
int type, code;
struct ifnet *outif = NULL;
- struct in6_addr origdst, src, *srcp = NULL;
+ struct in6_addr src, *srcp = NULL;
+ uint32_t zoneid;
/* too short to reflect */
if (off < sizeof(struct ip6_hdr)) {
@@ -2204,43 +2209,20 @@ icmp6_reflect(struct mbuf *m, size_t off
type = icmp6->icmp6_type; /* keep type for statistics */
code = icmp6->icmp6_code; /* ditto. */
- origdst = ip6->ip6_dst;
- /*
- * ip6_input() drops a packet if its src is multicast.
- * So, the src is never multicast.
- */
- ip6->ip6_dst = ip6->ip6_src;
-
/*
* If the incoming packet was addressed directly to us (i.e. unicast),
* use dst as the src for the reply.
* The IN6_IFF_NOTREADY case should be VERY rare, but is possible
* (for example) when we encounter an error while forwarding procedure
* destined to a duplicated address of ours.
- * Note that ip6_getdstifaddr() may fail if we are in an error handling
- * procedure of an outgoing packet of our own, in which case we need
- * to search in the ifaddr list.
*/
- if (!IN6_IS_ADDR_MULTICAST(&origdst)) {
- if ((ia = ip6_getdstifaddr(m))) {
- if (!(ia->ia6_flags &
- (IN6_IFF_ANYCAST|IN6_IFF_NOTREADY)))
- srcp = &ia->ia_addr.sin6_addr;
- } else {
- struct sockaddr_in6 d;
-
- bzero(&d, sizeof(d));
- d.sin6_family = AF_INET6;
- d.sin6_len = sizeof(d);
- d.sin6_addr = origdst;
- ia = (struct in6_ifaddr *)
- ifa_ifwithaddr((struct sockaddr *)&d);
- if (ia &&
- !(ia->ia6_flags &
- (IN6_IFF_ANYCAST|IN6_IFF_NOTREADY))) {
- srcp = &ia->ia_addr.sin6_addr;
- }
- }
+ zoneid = in6_getscopezone(m->m_hdr.rcvif,
+ in6_addrscope(&ip6->ip6_dst));
+ if (!IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
+ ia = in6ifa_ifwithaddr(&ip6->ip6_dst, zoneid);
+ if (ia != NULL && !(ia->ia6_flags &
+ (IN6_IFF_ANYCAST | IN6_IFF_NOTREADY)))
+ srcp = &ia->ia_addr.sin6_addr;
}
if (srcp == NULL) {
@@ -2256,7 +2238,8 @@ icmp6_reflect(struct mbuf *m, size_t off
bzero(&sin6, sizeof(sin6));
sin6.sin6_family = AF_INET6;
sin6.sin6_len = sizeof(sin6);
- sin6.sin6_addr = ip6->ip6_dst; /* zone ID should be embedded */
+ sin6.sin6_addr = ip6->ip6_dst;
+ sin6.sin6_scope_id = zoneid;
bzero(&ro, sizeof(ro));
e = in6_selectsrc(&sin6, NULL, NULL, &ro, NULL, &outif, &src);
@@ -2273,6 +2256,11 @@ icmp6_reflect(struct mbuf *m, size_t off
srcp = &src;
}
+ /*
+ * ip6_input() drops a packet if its src is multicast.
+ * So, the src is never multicast.
+ */
+ ip6->ip6_dst = ip6->ip6_src;
ip6->ip6_src = *srcp;
ip6->ip6_flow = 0;
ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
More information about the svn-src-user
mailing list