summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/inet/udp/udp.c
diff options
context:
space:
mode:
authorKeith M Wesolowski <wesolows@foobazco.org>2014-03-05 16:14:42 +0000
committerKeith M Wesolowski <wesolows@foobazco.org>2014-03-05 16:14:42 +0000
commit2d02bb4655a4bcc0b7f2e0b0e661270f13d0f8a3 (patch)
tree93668f0237e432973b0c0d568ce4c24afbe505ad /usr/src/uts/common/inet/udp/udp.c
parenta16c14a26a4c72468482a0026ecaabafeb24fff9 (diff)
parenta1ca8b43681e3163e9f085ab65b8b6de1848d8ac (diff)
downloadillumos-joyent-2d02bb4655a4bcc0b7f2e0b0e661270f13d0f8a3.tar.gz
[illumos-gate merge]
commit a1ca8b43681e3163e9f085ab65b8b6de1848d8ac 4596 Callers of ip_srcid_find_id() need to be more careful commit 7298ed33f6dda314aee9fee22d0dccfb09cc0ef6 4314 mountd(1m): Options are not related to Solaris
Diffstat (limited to 'usr/src/uts/common/inet/udp/udp.c')
-rw-r--r--usr/src/uts/common/inet/udp/udp.c53
1 files changed, 36 insertions, 17 deletions
diff --git a/usr/src/uts/common/inet/udp/udp.c b/usr/src/uts/common/inet/udp/udp.c
index e6dfd3efe9..4a6e835b67 100644
--- a/usr/src/uts/common/inet/udp/udp.c
+++ b/usr/src/uts/common/inet/udp/udp.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved.
*/
/* Copyright (c) 1990 Mentat Inc. */
@@ -2714,6 +2715,8 @@ udp_output_ancillary(conn_t *connp, sin_t *sin, sin6_t *sin6, mblk_t *mp,
ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
ixa->ixa_flags |= IXAF_IS_IPV4;
} else if (sin6 != NULL) {
+ boolean_t v4mapped;
+
v6dst = sin6->sin6_addr;
dstport = sin6->sin6_port;
flowinfo = sin6->sin6_flowinfo;
@@ -2724,14 +2727,20 @@ udp_output_ancillary(conn_t *connp, sin_t *sin, sin6_t *sin6, mblk_t *mp,
} else {
ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
}
- if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) {
- ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
- connp->conn_netstack);
- }
- if (IN6_IS_ADDR_V4MAPPED(&v6dst))
+ v4mapped = IN6_IS_ADDR_V4MAPPED(&v6dst);
+ if (v4mapped)
ixa->ixa_flags |= IXAF_IS_IPV4;
else
ixa->ixa_flags &= ~IXAF_IS_IPV4;
+ if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) {
+ if (ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
+ v4mapped, connp->conn_netstack)) {
+ /* Mismatch - v4mapped/v6 specified by srcid. */
+ mutex_exit(&connp->conn_lock);
+ error = EADDRNOTAVAIL;
+ goto failed; /* Does freemsg() and mib. */
+ }
+ }
} else {
/* Connected case */
v6dst = connp->conn_faddr_v6;
@@ -3722,14 +3731,13 @@ udp_output_newdst(conn_t *connp, mblk_t *data_mp, sin_t *sin, sin6_t *sin6,
IN6_IPADDR_TO_V4MAPPED(sin->sin_addr.s_addr, &v6dst);
dstport = sin->sin_port;
flowinfo = 0;
+ /* Don't bother with ip_srcid_find_id(), but indicate anyway. */
srcid = 0;
ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
- if (srcid != 0 && V4_PART_OF_V6(&v6src) == INADDR_ANY) {
- ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
- connp->conn_netstack);
- }
ixa->ixa_flags |= IXAF_IS_IPV4;
} else {
+ boolean_t v4mapped;
+
v6dst = sin6->sin6_addr;
dstport = sin6->sin6_port;
flowinfo = sin6->sin6_flowinfo;
@@ -3740,14 +3748,20 @@ udp_output_newdst(conn_t *connp, mblk_t *data_mp, sin_t *sin, sin6_t *sin6,
} else {
ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
}
- if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) {
- ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
- connp->conn_netstack);
- }
- if (IN6_IS_ADDR_V4MAPPED(&v6dst))
+ v4mapped = IN6_IS_ADDR_V4MAPPED(&v6dst);
+ if (v4mapped)
ixa->ixa_flags |= IXAF_IS_IPV4;
else
ixa->ixa_flags &= ~IXAF_IS_IPV4;
+ if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) {
+ if (ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
+ v4mapped, connp->conn_netstack)) {
+ /* Mismatched v4mapped/v6 specified by srcid. */
+ mutex_exit(&connp->conn_lock);
+ error = EADDRNOTAVAIL;
+ goto ud_error;
+ }
+ }
}
/* Handle IP_PKTINFO/IPV6_PKTINFO setting source address. */
if (connp->conn_xmit_ipp.ipp_fields & IPPF_ADDR) {
@@ -5526,6 +5540,7 @@ udp_do_connect(conn_t *connp, const struct sockaddr *sa, socklen_t len,
uint_t scopeid = 0;
uint_t srcid = 0;
in6_addr_t v6src = connp->conn_saddr_v6;
+ boolean_t v4mapped;
udp = connp->conn_udp;
us = udp->udp_us;
@@ -5554,11 +5569,15 @@ udp_do_connect(conn_t *connp, const struct sockaddr *sa, socklen_t len,
v6dst = sin6->sin6_addr;
dstport = sin6->sin6_port;
srcid = sin6->__sin6_src_id;
+ v4mapped = IN6_IS_ADDR_V4MAPPED(&v6dst);
if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) {
- ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
- connp->conn_netstack);
+ if (ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
+ v4mapped, connp->conn_netstack)) {
+ /* Mismatch v4mapped/v6 specified by srcid. */
+ return (EADDRNOTAVAIL);
+ }
}
- if (IN6_IS_ADDR_V4MAPPED(&v6dst)) {
+ if (v4mapped) {
if (connp->conn_ipv6_v6only)
return (EADDRNOTAVAIL);