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 2013 Nexenta Systems, Inc. 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>
*** 2712,2721 ****
--- 2713,2724 ----
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;
+
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) {
*** 2722,2739 ****
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;
dstport = connp->conn_fport;
flowinfo = connp->conn_flowinfo;
--- 2725,2748 ----
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)) {
+ /* 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;
dstport = connp->conn_fport;
flowinfo = connp->conn_flowinfo;
*** 3720,3737 ****
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) {
--- 3729,3745 ----
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) {
*** 3738,3756 ****
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) {
--- 3746,3770 ----
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) {
*** 5524,5533 ****
--- 5538,5548 ----
ip_xmit_attr_t *ixa;
ip_xmit_attr_t *oldixa;
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;
/*
*** 5552,5566 ****
case sizeof (sin6_t):
sin6 = (sin6_t *)sa;
v6dst = sin6->sin6_addr;
dstport = sin6->sin6_port;
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);
}
! if (IN6_IS_ADDR_V4MAPPED(&v6dst)) {
if (connp->conn_ipv6_v6only)
return (EADDRNOTAVAIL);
/*
* Destination adress is mapped IPv6 address.
--- 5567,5585 ----
case sizeof (sin6_t):
sin6 = (sin6_t *)sa;
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)) {
! if (ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
! v4mapped, connp->conn_netstack)) {
! /* Mismatch v4mapped/v6 specified by srcid. */
! return (EADDRNOTAVAIL);
}
! }
! if (v4mapped) {
if (connp->conn_ipv6_v6only)
return (EADDRNOTAVAIL);
/*
* Destination adress is mapped IPv6 address.