svn commit: r257030 - user/ae/inet6/sys/netinet6

Andrey V. Elsukov ae at FreeBSD.org
Thu Oct 24 00:39:27 UTC 2013


Author: ae
Date: Thu Oct 24 00:39:27 2013
New Revision: 257030
URL: http://svnweb.freebsd.org/changeset/base/257030

Log:
  Scope related cleanup in rip6_output():
  * remove sa6_embedscope() and in6_setscope() calls;
  * rip6_output() calls in6_selectsrc, so it always has outgoing interface
    and we can use IPV6_USEROIF when calling ip6_output.
  * add sa6_checkzone() to rip6_send. Application always must provide
    a proper scope zone id.

Modified:
  user/ae/inet6/sys/netinet6/raw_ip6.c

Modified: user/ae/inet6/sys/netinet6/raw_ip6.c
==============================================================================
--- user/ae/inet6/sys/netinet6/raw_ip6.c	Thu Oct 24 00:33:29 2013	(r257029)
+++ user/ae/inet6/sys/netinet6/raw_ip6.c	Thu Oct 24 00:39:27 2013	(r257030)
@@ -389,13 +389,7 @@ rip6_ctlinput(int cmd, struct sockaddr *
  * may have setup with control call.
  */
 int
-#if __STDC__
 rip6_output(struct mbuf *m, ...)
-#else
-rip6_output(m, va_alist)
-	struct mbuf *m;
-	va_dcl
-#endif
 {
 	struct mbuf *control;
 	struct m_tag *mtag;
@@ -409,8 +403,6 @@ rip6_output(m, va_alist)
 	struct ip6_pktopts opt, *optp;
 	struct ifnet *oifp = NULL;
 	int type = 0, code = 0;		/* for ICMPv6 output statistics only */
-	int scope_ambiguous = 0;
-	int use_defzone = 0;
 	struct in6_addr in6a;
 	va_list ap;
 
@@ -435,21 +427,6 @@ rip6_output(m, va_alist)
 		optp = in6p->in6p_outputopts;
 
 	/*
-	 * Check and convert scope zone ID into internal form.
-	 *
-	 * XXX: we may still need to determine the zone later.
-	 */
-	if (!(so->so_state & SS_ISCONNECTED)) {
-		if (!optp || !optp->ip6po_pktinfo ||
-		    !optp->ip6po_pktinfo->ipi6_ifindex)
-			use_defzone = V_ip6_use_defzone;
-		if (dstsock->sin6_scope_id == 0 && !use_defzone)
-			scope_ambiguous = 1;
-		if ((error = sa6_embedscope(dstsock, use_defzone)) != 0)
-			goto bad;
-	}
-
-	/*
 	 * For an ICMPv6 packet, we should know its type and code to update
 	 * statistics.
 	 */
@@ -483,20 +460,6 @@ rip6_output(m, va_alist)
 	if (error != 0)
 		goto bad;
 	ip6->ip6_src = in6a;
-
-	if (oifp && scope_ambiguous) {
-		/*
-		 * Application should provide a proper zone ID or the use of
-		 * default zone IDs should be enabled.  Unfortunately, some
-		 * applications do not behave as it should, so we need a
-		 * workaround.  Even if an appropriate ID is not determined
-		 * (when it's required), if we can determine the outgoing
-		 * interface. determine the zone ID based on the interface.
-		 */
-		error = in6_setscope(&dstsock->sin6_addr, oifp, NULL);
-		if (error != 0)
-			goto bad;
-	}
 	ip6->ip6_dst = dstsock->sin6_addr;
 
 	/*
@@ -559,10 +522,10 @@ rip6_output(m, va_alist)
 		}
 	}
 
-	error = ip6_output(m, optp, NULL, 0, in6p->in6p_moptions, &oifp, in6p);
+	error = ip6_output(m, optp, NULL, IPV6_USEROIF, in6p->in6p_moptions,
+	    &oifp, in6p);
 	if (so->so_proto->pr_protocol == IPPROTO_ICMPV6) {
-		if (oifp)
-			icmp6_ifoutstat_inc(oifp, type, code);
+		icmp6_ifoutstat_inc(oifp, type, code);
 		ICMP6STAT_INC(icp6s_outhist[type]);
 	} else
 		RIP6STAT_INC(rip6s_opackets);
@@ -889,8 +852,9 @@ rip6_send(struct socket *so, int flags, 
 		tmp.sin6_family = AF_INET6;
 		tmp.sin6_len = sizeof(struct sockaddr_in6);
 		INP_RLOCK(inp);
-		bcopy(&inp->in6p_faddr, &tmp.sin6_addr,
-		    sizeof(struct in6_addr));
+		tmp.sin6_addr = inp->in6p_faddr;
+		if (IN6_IS_ADDR_LINKLOCAL(&tmp.sin6_addr))
+			tmp.sin6_scope_id = inp->in6p_zoneid;
 		INP_RUNLOCK(inp);
 		dst = &tmp;
 	} else {
@@ -918,6 +882,15 @@ rip6_send(struct socket *so, int flags, 
 			m_freem(m);
 			return(EAFNOSUPPORT);
 		}
+		/*
+		 * Application must provide a proper zone ID or the use of
+		 * default zone IDs should be enabled.
+		 */
+		ret = sa6_checkzone(dst);
+		if (ret != 0) {
+			m_freem(m);
+			return (ret);
+		}
 	}
 	ret = rip6_output(m, so, dst, control);
 	return (ret);


More information about the svn-src-user mailing list