svn commit: r257088 - user/ae/inet6/sys/netinet6
Andrey V. Elsukov
ae at FreeBSD.org
Fri Oct 25 02:16:37 UTC 2013
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
More information about the svn-src-user
mailing list