Print this page
4596 Callers of ip_srcid_find_id() need to be more careful
*** 19,28 ****
--- 19,29 ----
* CDDL HEADER END
*/
/*
* Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved.
*/
/* Copyright (c) 1990 Mentat Inc. */
#include <sys/types.h>
#include <sys/stream.h>
*** 766,778 ****
flowinfo = sin6->sin6_flowinfo;
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
scopeid = sin6->sin6_scope_id;
srcid = sin6->__sin6_src_id;
if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) {
! ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
! connp->conn_netstack);
}
break;
}
/*
* If there is a different thread using conn_ixa then we get a new
--- 767,783 ----
flowinfo = sin6->sin6_flowinfo;
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
scopeid = sin6->sin6_scope_id;
srcid = sin6->__sin6_src_id;
if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) {
! /* Due to check above, we know sin6_addr is v6-only. */
! if (!ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
! B_FALSE, connp->conn_netstack)) {
! /* Mismatch - v6src would be v4mapped. */
! return (EADDRNOTAVAIL);
}
+ }
break;
}
/*
* If there is a different thread using conn_ixa then we get a new
*** 3335,3345 ****
in6_addr_t v6src;
in6_addr_t v6dst;
in6_addr_t v6nexthop;
in_port_t dstport;
uint32_t flowinfo;
- uint_t srcid;
int is_absreq_failure = 0;
conn_opt_arg_t coas, *coa;
ASSERT(tudr_mp != NULL || msg != NULL);
--- 3340,3349 ----
*** 3438,3447 ****
--- 3442,3454 ----
dstport = sin->sin_port;
flowinfo = 0;
ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
ixa->ixa_flags |= IXAF_IS_IPV4;
} else if (sin6 != NULL) {
+ boolean_t v4mapped;
+ uint_t srcid;
+
v6dst = sin6->sin6_addr;
dstport = sin6->sin6_port;
flowinfo = sin6->sin6_flowinfo;
srcid = sin6->__sin6_src_id;
if (IN6_IS_ADDR_LINKSCOPE(&v6dst) && sin6->sin6_scope_id != 0) {
*** 3448,3465 ****
ixa->ixa_scopeid = sin6->sin6_scope_id;
ixa->ixa_flags |= IXAF_SCOPEID_SET;
} 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))
ixa->ixa_flags |= IXAF_IS_IPV4;
else
ixa->ixa_flags &= ~IXAF_IS_IPV4;
} else {
/* Connected case */
v6dst = connp->conn_faddr_v6;
flowinfo = connp->conn_flowinfo;
}
--- 3455,3478 ----
ixa->ixa_scopeid = sin6->sin6_scope_id;
ixa->ixa_flags |= IXAF_SCOPEID_SET;
} else {
ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
}
! 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 failed; /* Does freemsg() and mib. */
+ }
+ }
} else {
/* Connected case */
v6dst = connp->conn_faddr_v6;
flowinfo = connp->conn_flowinfo;
}
*** 4417,4434 ****
v6src = connp->conn_saddr_v6;
if (sin != NULL) {
IN6_IPADDR_TO_V4MAPPED(sin->sin_addr.s_addr, &v6dst);
dstport = sin->sin_port;
flowinfo = 0;
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 {
v6dst = sin6->sin6_addr;
dstport = sin6->sin6_port;
flowinfo = sin6->sin6_flowinfo;
srcid = sin6->__sin6_src_id;
if (IN6_IS_ADDR_LINKSCOPE(&v6dst) && sin6->sin6_scope_id != 0) {
--- 4430,4446 ----
v6src = connp->conn_saddr_v6;
if (sin != NULL) {
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;
ixa->ixa_flags |= IXAF_IS_IPV4;
} else {
+ boolean_t v4mapped;
+
v6dst = sin6->sin6_addr;
dstport = sin6->sin6_port;
flowinfo = sin6->sin6_flowinfo;
srcid = sin6->__sin6_src_id;
if (IN6_IS_ADDR_LINKSCOPE(&v6dst) && sin6->sin6_scope_id != 0) {
*** 4435,4453 ****
ixa->ixa_scopeid = sin6->sin6_scope_id;
ixa->ixa_flags |= IXAF_SCOPEID_SET;
} 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))
ixa->ixa_flags |= IXAF_IS_IPV4;
else
ixa->ixa_flags &= ~IXAF_IS_IPV4;
}
/* Handle IP_PKTINFO/IPV6_PKTINFO setting source address. */
if (connp->conn_xmit_ipp.ipp_fields & IPPF_ADDR) {
ip_pkt_t *ipp = &connp->conn_xmit_ipp;
if (ixa->ixa_flags & IXAF_IS_IPV4) {
--- 4447,4471 ----
ixa->ixa_scopeid = sin6->sin6_scope_id;
ixa->ixa_flags |= IXAF_SCOPEID_SET;
} else {
ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
}
! 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) {
ip_pkt_t *ipp = &connp->conn_xmit_ipp;
if (ixa->ixa_flags & IXAF_IS_IPV4) {