Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 13 Feb 2013 09:07:38 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r246754 - user/ae/inet6/sys/netinet6
Message-ID:  <201302130907.r1D97c0F002228@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201302130907.r1D97c0F002228>