Print this page
4596 Callers of ip_srcid_find_id() need to be more careful


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.

  24  */
  25 /* Copyright (c) 1990 Mentat Inc. */
  26 
  27 #include <sys/types.h>
  28 #include <sys/stream.h>
  29 #include <sys/stropts.h>
  30 #include <sys/strlog.h>
  31 #include <sys/strsun.h>
  32 #define _SUN_TPI_VERSION 2
  33 #include <sys/tihdr.h>
  34 #include <sys/timod.h>
  35 #include <sys/ddi.h>
  36 #include <sys/sunddi.h>
  37 #include <sys/strsubr.h>
  38 #include <sys/suntpi.h>
  39 #include <sys/xti_inet.h>
  40 #include <sys/kmem.h>
  41 #include <sys/cred_impl.h>
  42 #include <sys/policy.h>
  43 #include <sys/priv.h>


2697         ASSERT(is_absreq_failure == 0);
2698 
2699         mutex_enter(&connp->conn_lock);
2700         /*
2701          * If laddr is unspecified then we look at sin6_src_id.
2702          * We will give precedence to a source address set with IPV6_PKTINFO
2703          * (aka IPPF_ADDR) but that is handled in build_hdrs. However, we don't
2704          * want ip_attr_connect to select a source (since it can fail) when
2705          * IPV6_PKTINFO is specified.
2706          * If this doesn't result in a source address then we get a source
2707          * from ip_attr_connect() below.
2708          */
2709         v6src = connp->conn_saddr_v6;
2710         if (sin != NULL) {
2711                 IN6_IPADDR_TO_V4MAPPED(sin->sin_addr.s_addr, &v6dst);
2712                 dstport = sin->sin_port;
2713                 flowinfo = 0;
2714                 ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
2715                 ixa->ixa_flags |= IXAF_IS_IPV4;
2716         } else if (sin6 != NULL) {


2717                 v6dst = sin6->sin6_addr;
2718                 dstport = sin6->sin6_port;
2719                 flowinfo = sin6->sin6_flowinfo;
2720                 srcid = sin6->__sin6_src_id;
2721                 if (IN6_IS_ADDR_LINKSCOPE(&v6dst) && sin6->sin6_scope_id != 0) {
2722                         ixa->ixa_scopeid = sin6->sin6_scope_id;
2723                         ixa->ixa_flags |= IXAF_SCOPEID_SET;
2724                 } else {
2725                         ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
2726                 }
2727                 if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) {
2728                         ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
2729                             connp->conn_netstack);
2730                 }
2731                 if (IN6_IS_ADDR_V4MAPPED(&v6dst))
2732                         ixa->ixa_flags |= IXAF_IS_IPV4;
2733                 else
2734                         ixa->ixa_flags &= ~IXAF_IS_IPV4;









2735         } else {
2736                 /* Connected case */
2737                 v6dst = connp->conn_faddr_v6;
2738                 dstport = connp->conn_fport;
2739                 flowinfo = connp->conn_flowinfo;
2740         }
2741         mutex_exit(&connp->conn_lock);
2742 
2743         /* Handle IP_PKTINFO/IPV6_PKTINFO setting source address. */
2744         if (ipp->ipp_fields & IPPF_ADDR) {
2745                 if (ixa->ixa_flags & IXAF_IS_IPV4) {
2746                         if (IN6_IS_ADDR_V4MAPPED(&ipp->ipp_addr))
2747                                 v6src = ipp->ipp_addr;
2748                 } else {
2749                         if (!IN6_IS_ADDR_V4MAPPED(&ipp->ipp_addr))
2750                                 v6src = ipp->ipp_addr;
2751                 }
2752         }
2753 
2754         ip_attr_nexthop(ipp, ixa, &v6dst, &v6nexthop);


3705                 goto ud_error;
3706         }
3707 
3708         /* In case previous destination was multicast or multirt */
3709         ip_attr_newdst(ixa);
3710 
3711         /*
3712          * If laddr is unspecified then we look at sin6_src_id.
3713          * We will give precedence to a source address set with IPV6_PKTINFO
3714          * (aka IPPF_ADDR) but that is handled in build_hdrs. However, we don't
3715          * want ip_attr_connect to select a source (since it can fail) when
3716          * IPV6_PKTINFO is specified.
3717          * If this doesn't result in a source address then we get a source
3718          * from ip_attr_connect() below.
3719          */
3720         v6src = connp->conn_saddr_v6;
3721         if (sin != NULL) {
3722                 IN6_IPADDR_TO_V4MAPPED(sin->sin_addr.s_addr, &v6dst);
3723                 dstport = sin->sin_port;
3724                 flowinfo = 0;

3725                 srcid = 0;
3726                 ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
3727                 if (srcid != 0 && V4_PART_OF_V6(&v6src) == INADDR_ANY) {
3728                         ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
3729                             connp->conn_netstack);
3730                 }
3731                 ixa->ixa_flags |= IXAF_IS_IPV4;
3732         } else {


3733                 v6dst = sin6->sin6_addr;
3734                 dstport = sin6->sin6_port;
3735                 flowinfo = sin6->sin6_flowinfo;
3736                 srcid = sin6->__sin6_src_id;
3737                 if (IN6_IS_ADDR_LINKSCOPE(&v6dst) && sin6->sin6_scope_id != 0) {
3738                         ixa->ixa_scopeid = sin6->sin6_scope_id;
3739                         ixa->ixa_flags |= IXAF_SCOPEID_SET;
3740                 } else {
3741                         ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
3742                 }
3743                 if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) {
3744                         ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
3745                             connp->conn_netstack);
3746                 }
3747                 if (IN6_IS_ADDR_V4MAPPED(&v6dst))
3748                         ixa->ixa_flags |= IXAF_IS_IPV4;
3749                 else
3750                         ixa->ixa_flags &= ~IXAF_IS_IPV4;







3751         }


3752         /* Handle IP_PKTINFO/IPV6_PKTINFO setting source address. */
3753         if (connp->conn_xmit_ipp.ipp_fields & IPPF_ADDR) {
3754                 ip_pkt_t *ipp = &connp->conn_xmit_ipp;
3755 
3756                 if (ixa->ixa_flags & IXAF_IS_IPV4) {
3757                         if (IN6_IS_ADDR_V4MAPPED(&ipp->ipp_addr))
3758                                 v6src = ipp->ipp_addr;
3759                 } else {
3760                         if (!IN6_IS_ADDR_V4MAPPED(&ipp->ipp_addr))
3761                                 v6src = ipp->ipp_addr;
3762                 }
3763         }
3764 
3765         ip_attr_nexthop(&connp->conn_xmit_ipp, ixa, &v6dst, &v6nexthop);
3766         mutex_exit(&connp->conn_lock);
3767 
3768         error = ip_attr_connect(connp, ixa, &v6src, &v6dst, &v6nexthop, dstport,
3769             &v6src, NULL, IPDF_ALLOW_MCBC | IPDF_VERIFY_DST | IPDF_IPSEC);
3770         switch (error) {
3771         case 0:


5509 udp_do_connect(conn_t *connp, const struct sockaddr *sa, socklen_t len,
5510     cred_t *cr, pid_t pid)
5511 {
5512         sin6_t          *sin6;
5513         sin_t           *sin;
5514         in6_addr_t      v6dst;
5515         ipaddr_t        v4dst;
5516         uint16_t        dstport;
5517         uint32_t        flowinfo;
5518         udp_fanout_t    *udpf;
5519         udp_t           *udp, *udp1;
5520         ushort_t        ipversion;
5521         udp_stack_t     *us;
5522         int             error;
5523         conn_t          *connp1;
5524         ip_xmit_attr_t  *ixa;
5525         ip_xmit_attr_t  *oldixa;
5526         uint_t          scopeid = 0;
5527         uint_t          srcid = 0;
5528         in6_addr_t      v6src = connp->conn_saddr_v6;

5529 
5530         udp = connp->conn_udp;
5531         us = udp->udp_us;
5532 
5533         /*
5534          * Address has been verified by the caller
5535          */
5536         switch (len) {
5537         default:
5538                 /*
5539                  * Should never happen
5540                  */
5541                 return (EINVAL);
5542 
5543         case sizeof (sin_t):
5544                 sin = (sin_t *)sa;
5545                 v4dst = sin->sin_addr.s_addr;
5546                 dstport = sin->sin_port;
5547                 IN6_IPADDR_TO_V4MAPPED(v4dst, &v6dst);
5548                 ASSERT(connp->conn_ipversion == IPV4_VERSION);
5549                 ipversion = IPV4_VERSION;
5550                 break;
5551 
5552         case sizeof (sin6_t):
5553                 sin6 = (sin6_t *)sa;
5554                 v6dst = sin6->sin6_addr;
5555                 dstport = sin6->sin6_port;
5556                 srcid = sin6->__sin6_src_id;

5557                 if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) {
5558                         ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
5559                             connp->conn_netstack);


5560                 }
5561                 if (IN6_IS_ADDR_V4MAPPED(&v6dst)) {

5562                         if (connp->conn_ipv6_v6only)
5563                                 return (EADDRNOTAVAIL);
5564 
5565                         /*
5566                          * Destination adress is mapped IPv6 address.
5567                          * Source bound address should be unspecified or
5568                          * IPv6 mapped address as well.
5569                          */
5570                         if (!IN6_IS_ADDR_UNSPECIFIED(
5571                             &connp->conn_bound_addr_v6) &&
5572                             !IN6_IS_ADDR_V4MAPPED(&connp->conn_bound_addr_v6)) {
5573                                 return (EADDRNOTAVAIL);
5574                         }
5575                         IN6_V4MAPPED_TO_IPADDR(&v6dst, v4dst);
5576                         ipversion = IPV4_VERSION;
5577                         flowinfo = 0;
5578                 } else {
5579                         ipversion = IPV6_VERSION;
5580                         flowinfo = sin6->sin6_flowinfo;
5581                         if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))




   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  24  * Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved.
  25  */
  26 /* Copyright (c) 1990 Mentat Inc. */
  27 
  28 #include <sys/types.h>
  29 #include <sys/stream.h>
  30 #include <sys/stropts.h>
  31 #include <sys/strlog.h>
  32 #include <sys/strsun.h>
  33 #define _SUN_TPI_VERSION 2
  34 #include <sys/tihdr.h>
  35 #include <sys/timod.h>
  36 #include <sys/ddi.h>
  37 #include <sys/sunddi.h>
  38 #include <sys/strsubr.h>
  39 #include <sys/suntpi.h>
  40 #include <sys/xti_inet.h>
  41 #include <sys/kmem.h>
  42 #include <sys/cred_impl.h>
  43 #include <sys/policy.h>
  44 #include <sys/priv.h>


2698         ASSERT(is_absreq_failure == 0);
2699 
2700         mutex_enter(&connp->conn_lock);
2701         /*
2702          * If laddr is unspecified then we look at sin6_src_id.
2703          * We will give precedence to a source address set with IPV6_PKTINFO
2704          * (aka IPPF_ADDR) but that is handled in build_hdrs. However, we don't
2705          * want ip_attr_connect to select a source (since it can fail) when
2706          * IPV6_PKTINFO is specified.
2707          * If this doesn't result in a source address then we get a source
2708          * from ip_attr_connect() below.
2709          */
2710         v6src = connp->conn_saddr_v6;
2711         if (sin != NULL) {
2712                 IN6_IPADDR_TO_V4MAPPED(sin->sin_addr.s_addr, &v6dst);
2713                 dstport = sin->sin_port;
2714                 flowinfo = 0;
2715                 ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
2716                 ixa->ixa_flags |= IXAF_IS_IPV4;
2717         } else if (sin6 != NULL) {
2718                 boolean_t v4mapped;
2719 
2720                 v6dst = sin6->sin6_addr;
2721                 dstport = sin6->sin6_port;
2722                 flowinfo = sin6->sin6_flowinfo;
2723                 srcid = sin6->__sin6_src_id;
2724                 if (IN6_IS_ADDR_LINKSCOPE(&v6dst) && sin6->sin6_scope_id != 0) {
2725                         ixa->ixa_scopeid = sin6->sin6_scope_id;
2726                         ixa->ixa_flags |= IXAF_SCOPEID_SET;
2727                 } else {
2728                         ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
2729                 }
2730                 v4mapped = IN6_IS_ADDR_V4MAPPED(&v6dst);
2731                 if (v4mapped)



2732                         ixa->ixa_flags |= IXAF_IS_IPV4;
2733                 else
2734                         ixa->ixa_flags &= ~IXAF_IS_IPV4;
2735                 if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) {
2736                         if (ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
2737                             v4mapped, connp->conn_netstack)) {
2738                                 /* Mismatch - v4mapped/v6 specified by srcid. */
2739                                 mutex_exit(&connp->conn_lock);
2740                                 error = EADDRNOTAVAIL;
2741                                 goto failed;    /* Does freemsg() and mib. */
2742                         }
2743                 }
2744         } else {
2745                 /* Connected case */
2746                 v6dst = connp->conn_faddr_v6;
2747                 dstport = connp->conn_fport;
2748                 flowinfo = connp->conn_flowinfo;
2749         }
2750         mutex_exit(&connp->conn_lock);
2751 
2752         /* Handle IP_PKTINFO/IPV6_PKTINFO setting source address. */
2753         if (ipp->ipp_fields & IPPF_ADDR) {
2754                 if (ixa->ixa_flags & IXAF_IS_IPV4) {
2755                         if (IN6_IS_ADDR_V4MAPPED(&ipp->ipp_addr))
2756                                 v6src = ipp->ipp_addr;
2757                 } else {
2758                         if (!IN6_IS_ADDR_V4MAPPED(&ipp->ipp_addr))
2759                                 v6src = ipp->ipp_addr;
2760                 }
2761         }
2762 
2763         ip_attr_nexthop(ipp, ixa, &v6dst, &v6nexthop);


3714                 goto ud_error;
3715         }
3716 
3717         /* In case previous destination was multicast or multirt */
3718         ip_attr_newdst(ixa);
3719 
3720         /*
3721          * If laddr is unspecified then we look at sin6_src_id.
3722          * We will give precedence to a source address set with IPV6_PKTINFO
3723          * (aka IPPF_ADDR) but that is handled in build_hdrs. However, we don't
3724          * want ip_attr_connect to select a source (since it can fail) when
3725          * IPV6_PKTINFO is specified.
3726          * If this doesn't result in a source address then we get a source
3727          * from ip_attr_connect() below.
3728          */
3729         v6src = connp->conn_saddr_v6;
3730         if (sin != NULL) {
3731                 IN6_IPADDR_TO_V4MAPPED(sin->sin_addr.s_addr, &v6dst);
3732                 dstport = sin->sin_port;
3733                 flowinfo = 0;
3734                 /* Don't bother with ip_srcid_find_id(), but indicate anyway. */
3735                 srcid = 0;
3736                 ixa->ixa_flags &= ~IXAF_SCOPEID_SET;




3737                 ixa->ixa_flags |= IXAF_IS_IPV4;
3738         } else {
3739                 boolean_t v4mapped;
3740 
3741                 v6dst = sin6->sin6_addr;
3742                 dstport = sin6->sin6_port;
3743                 flowinfo = sin6->sin6_flowinfo;
3744                 srcid = sin6->__sin6_src_id;
3745                 if (IN6_IS_ADDR_LINKSCOPE(&v6dst) && sin6->sin6_scope_id != 0) {
3746                         ixa->ixa_scopeid = sin6->sin6_scope_id;
3747                         ixa->ixa_flags |= IXAF_SCOPEID_SET;
3748                 } else {
3749                         ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
3750                 }
3751                 v4mapped = IN6_IS_ADDR_V4MAPPED(&v6dst);
3752                 if (v4mapped)



3753                         ixa->ixa_flags |= IXAF_IS_IPV4;
3754                 else
3755                         ixa->ixa_flags &= ~IXAF_IS_IPV4;
3756                 if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) {
3757                         if (ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
3758                             v4mapped, connp->conn_netstack)) {
3759                                 /* Mismatched v4mapped/v6 specified by srcid. */
3760                                 mutex_exit(&connp->conn_lock);
3761                                 error = EADDRNOTAVAIL;
3762                                 goto ud_error;
3763                         }
3764                 }
3765         }
3766         /* Handle IP_PKTINFO/IPV6_PKTINFO setting source address. */
3767         if (connp->conn_xmit_ipp.ipp_fields & IPPF_ADDR) {
3768                 ip_pkt_t *ipp = &connp->conn_xmit_ipp;
3769 
3770                 if (ixa->ixa_flags & IXAF_IS_IPV4) {
3771                         if (IN6_IS_ADDR_V4MAPPED(&ipp->ipp_addr))
3772                                 v6src = ipp->ipp_addr;
3773                 } else {
3774                         if (!IN6_IS_ADDR_V4MAPPED(&ipp->ipp_addr))
3775                                 v6src = ipp->ipp_addr;
3776                 }
3777         }
3778 
3779         ip_attr_nexthop(&connp->conn_xmit_ipp, ixa, &v6dst, &v6nexthop);
3780         mutex_exit(&connp->conn_lock);
3781 
3782         error = ip_attr_connect(connp, ixa, &v6src, &v6dst, &v6nexthop, dstport,
3783             &v6src, NULL, IPDF_ALLOW_MCBC | IPDF_VERIFY_DST | IPDF_IPSEC);
3784         switch (error) {
3785         case 0:


5523 udp_do_connect(conn_t *connp, const struct sockaddr *sa, socklen_t len,
5524     cred_t *cr, pid_t pid)
5525 {
5526         sin6_t          *sin6;
5527         sin_t           *sin;
5528         in6_addr_t      v6dst;
5529         ipaddr_t        v4dst;
5530         uint16_t        dstport;
5531         uint32_t        flowinfo;
5532         udp_fanout_t    *udpf;
5533         udp_t           *udp, *udp1;
5534         ushort_t        ipversion;
5535         udp_stack_t     *us;
5536         int             error;
5537         conn_t          *connp1;
5538         ip_xmit_attr_t  *ixa;
5539         ip_xmit_attr_t  *oldixa;
5540         uint_t          scopeid = 0;
5541         uint_t          srcid = 0;
5542         in6_addr_t      v6src = connp->conn_saddr_v6;
5543         boolean_t       v4mapped;
5544 
5545         udp = connp->conn_udp;
5546         us = udp->udp_us;
5547 
5548         /*
5549          * Address has been verified by the caller
5550          */
5551         switch (len) {
5552         default:
5553                 /*
5554                  * Should never happen
5555                  */
5556                 return (EINVAL);
5557 
5558         case sizeof (sin_t):
5559                 sin = (sin_t *)sa;
5560                 v4dst = sin->sin_addr.s_addr;
5561                 dstport = sin->sin_port;
5562                 IN6_IPADDR_TO_V4MAPPED(v4dst, &v6dst);
5563                 ASSERT(connp->conn_ipversion == IPV4_VERSION);
5564                 ipversion = IPV4_VERSION;
5565                 break;
5566 
5567         case sizeof (sin6_t):
5568                 sin6 = (sin6_t *)sa;
5569                 v6dst = sin6->sin6_addr;
5570                 dstport = sin6->sin6_port;
5571                 srcid = sin6->__sin6_src_id;
5572                 v4mapped = IN6_IS_ADDR_V4MAPPED(&v6dst);
5573                 if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) {
5574                         if (ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
5575                             v4mapped, connp->conn_netstack)) {
5576                                 /* Mismatch v4mapped/v6 specified by srcid. */
5577                                 return (EADDRNOTAVAIL);
5578                         }
5579                 }
5580                 if (v4mapped) {
5581                         if (connp->conn_ipv6_v6only)
5582                                 return (EADDRNOTAVAIL);
5583 
5584                         /*
5585                          * Destination adress is mapped IPv6 address.
5586                          * Source bound address should be unspecified or
5587                          * IPv6 mapped address as well.
5588                          */
5589                         if (!IN6_IS_ADDR_UNSPECIFIED(
5590                             &connp->conn_bound_addr_v6) &&
5591                             !IN6_IS_ADDR_V4MAPPED(&connp->conn_bound_addr_v6)) {
5592                                 return (EADDRNOTAVAIL);
5593                         }
5594                         IN6_V4MAPPED_TO_IPADDR(&v6dst, v4dst);
5595                         ipversion = IPV4_VERSION;
5596                         flowinfo = 0;
5597                 } else {
5598                         ipversion = IPV6_VERSION;
5599                         flowinfo = sin6->sin6_flowinfo;
5600                         if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))