From owner-svn-src-user@FreeBSD.ORG Fri Oct 25 02:16:36 2013 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id CD2C492E; Fri, 25 Oct 2013 02:16:36 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id BB0062113; Fri, 25 Oct 2013 02:16:36 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r9P2GaNQ042529; Fri, 25 Oct 2013 02:16:36 GMT (envelope-from ae@svn.freebsd.org) Received: (from ae@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r9P2GatK042528; Fri, 25 Oct 2013 02:16:36 GMT (envelope-from ae@svn.freebsd.org) Message-Id: <201310250216.r9P2GatK042528@svn.freebsd.org> From: "Andrey V. Elsukov" Date: Fri, 25 Oct 2013 02:16:36 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r257088 - user/ae/inet6/sys/netinet6 X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 25 Oct 2013 02:16:37 -0000 Author: ae Date: Fri Oct 25 02:16:36 2013 New Revision: 257088 URL: http://svnweb.freebsd.org/changeset/base/257088 Log: Scope related cleanup in udp6_output(): * remove sa6_embedscope() and in6_setscope() calls; * move address validation check from udp6_output() to udp6_send(); * when address isn't specified, try to determine outgoing interface from inc->in6p_zoneid; * use IPV6_USEROIF for ip6_output() when outgoing interface is known. Modified: user/ae/inet6/sys/netinet6/udp6_usrreq.c Modified: user/ae/inet6/sys/netinet6/udp6_usrreq.c ============================================================================== --- user/ae/inet6/sys/netinet6/udp6_usrreq.c Fri Oct 25 01:49:08 2013 (r257087) +++ user/ae/inet6/sys/netinet6/udp6_usrreq.c Fri Oct 25 02:16:36 2013 (r257088) @@ -602,39 +602,17 @@ udp6_output(struct inpcb *inp, struct mb struct in6_addr *laddr, *faddr, in6a; struct sockaddr_in6 *sin6 = NULL; struct ifnet *oifp = NULL; - int scope_ambiguous = 0; u_short fport; int error = 0; struct ip6_pktopts *optp, opt; int af = AF_INET6, hlen = sizeof(struct ip6_hdr); int flags; - struct sockaddr_in6 tmp; INP_WLOCK_ASSERT(inp); INP_HASH_WLOCK_ASSERT(inp->inp_pcbinfo); - if (addr6) { - /* addr6 has been validated in udp6_send(). */ - sin6 = (struct sockaddr_in6 *)addr6; - - /* protect *sin6 from overwrites */ - tmp = *sin6; - sin6 = &tmp; - - /* - * 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, - * we'll see if we can determine the outgoing interface. If we - * can, determine the zone ID based on the interface below. - */ - if (sin6->sin6_scope_id == 0 && !V_ip6_use_defzone) - scope_ambiguous = 1; - if ((error = sa6_embedscope(sin6, V_ip6_use_defzone)) != 0) - return (error); - } - + /* addr6 has been validated in udp6_send(). */ + sin6 = (struct sockaddr_in6 *)addr6; if (control) { if ((error = ip6_setpktopts(control, &opt, inp->in6p_outputopts, td->td_ucred, IPPROTO_UDP)) != 0) @@ -700,11 +678,6 @@ udp6_output(struct inpcb *inp, struct mb td->td_ucred, &oifp, &in6a); if (error) goto release; - if (oifp && scope_ambiguous && - (error = in6_setscope(&sin6->sin6_addr, - oifp, NULL))) { - goto release; - } laddr = &in6a; } else laddr = &inp->in6p_laddr; /* XXX */ @@ -743,6 +716,8 @@ udp6_output(struct inpcb *inp, struct mb laddr = &inp->in6p_laddr; faddr = &inp->in6p_faddr; fport = inp->inp_fport; + if (inp->in6p_zoneid != 0) + oifp = in6_getlinkifnet(inp->in6p_zoneid); } if (af == AF_INET) @@ -786,12 +761,12 @@ udp6_output(struct inpcb *inp, struct mb m->m_pkthdr.csum_flags = CSUM_UDP_IPV6; m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum); - flags = 0; + flags = oifp ? IPV6_USEROIF: 0; UDP_PROBE(send, NULL, inp, ip6, inp, udp6); UDPSTAT_INC(udps_opackets); error = ip6_output(m, optp, NULL, flags, inp->in6p_moptions, - NULL, inp); + &oifp, inp); break; case AF_INET: error = EAFNOSUPPORT; @@ -1094,6 +1069,13 @@ udp6_send(struct socket *so, int flags, error = EAFNOSUPPORT; goto bad; } + /* + * Application must provide a proper zone ID or the use of + * default zone IDs should be enabled. + */ + error = sa6_checkzone((struct sockaddr_in6*)addr); + if (error != 0) + goto bad; } #ifdef INET