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 (c) 2013 by Delphix. 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/cmn_err.h>
  41 #include <sys/kmem.h>
  42 #include <sys/cred.h>
  43 #include <sys/policy.h>


 751                 dstport = sin->sin_port;
 752                 IN6_IPADDR_TO_V4MAPPED(v4dst, &v6dst);
 753                 ASSERT(connp->conn_ipversion == IPV4_VERSION);
 754                 break;
 755 
 756         case sizeof (sin6_t):
 757                 sin6 = (sin6_t *)sa;
 758 
 759                 /* No support for mapped addresses on raw sockets */
 760                 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
 761                         return (EADDRNOTAVAIL);
 762                 }
 763                 v6dst = sin6->sin6_addr;
 764                 dstport = sin6->sin6_port;
 765                 ASSERT(connp->conn_ipversion == IPV6_VERSION);
 766                 flowinfo = sin6->sin6_flowinfo;
 767                 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
 768                         scopeid = sin6->sin6_scope_id;
 769                 srcid = sin6->__sin6_src_id;
 770                 if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) {
 771                         ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
 772                             connp->conn_netstack);



 773                 }

 774                 break;
 775         }
 776 
 777         /*
 778          * If there is a different thread using conn_ixa then we get a new
 779          * copy and cut the old one loose from conn_ixa. Otherwise we use
 780          * conn_ixa and prevent any other thread from using/changing it.
 781          * Once connect() is done other threads can use conn_ixa since the
 782          * refcnt will be back at one.
 783          * We defer updating conn_ixa until later to handle any concurrent
 784          * conn_ixa_cleanup thread.
 785          */
 786         ixa = conn_get_ixa(connp, B_FALSE);
 787         if (ixa == NULL)
 788                 return (ENOMEM);
 789 
 790         mutex_enter(&connp->conn_lock);
 791         /*
 792          * This icmp_t must have bound already before doing a connect.
 793          * Reject if a connect is in progress (we drop conn_lock during


3320  * Handle T_UNITDATA_REQ with options. Both IPv4 and IPv6
3321  * Either tudr_mp or msg is set. If tudr_mp we take ancillary data from
3322  * the TPI options, otherwise we take them from msg_control.
3323  * If both sin and sin6 is set it is a connected socket and we use conn_faddr.
3324  * Always consumes mp; never consumes tudr_mp.
3325  */
3326 static int
3327 icmp_output_ancillary(conn_t *connp, sin_t *sin, sin6_t *sin6, mblk_t *mp,
3328     mblk_t *tudr_mp, struct nmsghdr *msg, cred_t *cr, pid_t pid)
3329 {
3330         icmp_t          *icmp = connp->conn_icmp;
3331         icmp_stack_t    *is = icmp->icmp_is;
3332         int             error;
3333         ip_xmit_attr_t  *ixa;
3334         ip_pkt_t        *ipp;
3335         in6_addr_t      v6src;
3336         in6_addr_t      v6dst;
3337         in6_addr_t      v6nexthop;
3338         in_port_t       dstport;
3339         uint32_t        flowinfo;
3340         uint_t          srcid;
3341         int             is_absreq_failure = 0;
3342         conn_opt_arg_t  coas, *coa;
3343 
3344         ASSERT(tudr_mp != NULL || msg != NULL);
3345 
3346         /*
3347          * Get ixa before checking state to handle a disconnect race.
3348          *
3349          * We need an exclusive copy of conn_ixa since the ancillary data
3350          * options might modify it. That copy has no pointers hence we
3351          * need to set them up once we've parsed the ancillary data.
3352          */
3353         ixa = conn_get_ixa_exclusive(connp);
3354         if (ixa == NULL) {
3355                 BUMP_MIB(&is->is_rawip_mib, rawipOutErrors);
3356                 freemsg(mp);
3357                 return (ENOMEM);
3358         }
3359         ASSERT(cr != NULL);
3360         ASSERT(!(ixa->ixa_free_flags & IXA_FREE_CRED));


3423         ASSERT(is_absreq_failure == 0);
3424 
3425         mutex_enter(&connp->conn_lock);
3426         /*
3427          * If laddr is unspecified then we look at sin6_src_id.
3428          * We will give precedence to a source address set with IPV6_PKTINFO
3429          * (aka IPPF_ADDR) but that is handled in build_hdrs. However, we don't
3430          * want ip_attr_connect to select a source (since it can fail) when
3431          * IPV6_PKTINFO is specified.
3432          * If this doesn't result in a source address then we get a source
3433          * from ip_attr_connect() below.
3434          */
3435         v6src = connp->conn_saddr_v6;
3436         if (sin != NULL) {
3437                 IN6_IPADDR_TO_V4MAPPED(sin->sin_addr.s_addr, &v6dst);
3438                 dstport = sin->sin_port;
3439                 flowinfo = 0;
3440                 ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
3441                 ixa->ixa_flags |= IXAF_IS_IPV4;
3442         } else if (sin6 != NULL) {



3443                 v6dst = sin6->sin6_addr;
3444                 dstport = sin6->sin6_port;
3445                 flowinfo = sin6->sin6_flowinfo;
3446                 srcid = sin6->__sin6_src_id;
3447                 if (IN6_IS_ADDR_LINKSCOPE(&v6dst) && sin6->sin6_scope_id != 0) {
3448                         ixa->ixa_scopeid = sin6->sin6_scope_id;
3449                         ixa->ixa_flags |= IXAF_SCOPEID_SET;
3450                 } else {
3451                         ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
3452                 }
3453                 if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) {
3454                         ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
3455                             connp->conn_netstack);
3456                 }
3457                 if (IN6_IS_ADDR_V4MAPPED(&v6dst))
3458                         ixa->ixa_flags |= IXAF_IS_IPV4;
3459                 else
3460                         ixa->ixa_flags &= ~IXAF_IS_IPV4;









3461         } else {
3462                 /* Connected case */
3463                 v6dst = connp->conn_faddr_v6;
3464                 flowinfo = connp->conn_flowinfo;
3465         }
3466         mutex_exit(&connp->conn_lock);
3467         /* Handle IP_PKTINFO/IPV6_PKTINFO setting source address. */
3468         if (ipp->ipp_fields & IPPF_ADDR) {
3469                 if (ixa->ixa_flags & IXAF_IS_IPV4) {
3470                         if (IN6_IS_ADDR_V4MAPPED(&ipp->ipp_addr))
3471                                 v6src = ipp->ipp_addr;
3472                 } else {
3473                         if (!IN6_IS_ADDR_V4MAPPED(&ipp->ipp_addr))
3474                                 v6src = ipp->ipp_addr;
3475                 }
3476         }
3477         /*
3478          * Allow source not assigned to the system
3479          * only if it is not a local addresses
3480          */


4402                 goto ud_error;
4403         }
4404 
4405         /* In case previous destination was multicast or multirt */
4406         ip_attr_newdst(ixa);
4407 
4408         /*
4409          * If laddr is unspecified then we look at sin6_src_id.
4410          * We will give precedence to a source address set with IPV6_PKTINFO
4411          * (aka IPPF_ADDR) but that is handled in build_hdrs. However, we don't
4412          * want ip_attr_connect to select a source (since it can fail) when
4413          * IPV6_PKTINFO is specified.
4414          * If this doesn't result in a source address then we get a source
4415          * from ip_attr_connect() below.
4416          */
4417         v6src = connp->conn_saddr_v6;
4418         if (sin != NULL) {
4419                 IN6_IPADDR_TO_V4MAPPED(sin->sin_addr.s_addr, &v6dst);
4420                 dstport = sin->sin_port;
4421                 flowinfo = 0;

4422                 srcid = 0;
4423                 ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
4424                 if (srcid != 0 && V4_PART_OF_V6(&v6src) == INADDR_ANY) {
4425                         ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
4426                             connp->conn_netstack);
4427                 }
4428                 ixa->ixa_flags |= IXAF_IS_IPV4;
4429         } else {


4430                 v6dst = sin6->sin6_addr;
4431                 dstport = sin6->sin6_port;
4432                 flowinfo = sin6->sin6_flowinfo;
4433                 srcid = sin6->__sin6_src_id;
4434                 if (IN6_IS_ADDR_LINKSCOPE(&v6dst) && sin6->sin6_scope_id != 0) {
4435                         ixa->ixa_scopeid = sin6->sin6_scope_id;
4436                         ixa->ixa_flags |= IXAF_SCOPEID_SET;
4437                 } else {
4438                         ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
4439                 }
4440                 if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) {
4441                         ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
4442                             connp->conn_netstack);
4443                 }
4444                 if (IN6_IS_ADDR_V4MAPPED(&v6dst))
4445                         ixa->ixa_flags |= IXAF_IS_IPV4;
4446                 else
4447                         ixa->ixa_flags &= ~IXAF_IS_IPV4;







4448         }


4449         /* Handle IP_PKTINFO/IPV6_PKTINFO setting source address. */
4450         if (connp->conn_xmit_ipp.ipp_fields & IPPF_ADDR) {
4451                 ip_pkt_t *ipp = &connp->conn_xmit_ipp;
4452 
4453                 if (ixa->ixa_flags & IXAF_IS_IPV4) {
4454                         if (IN6_IS_ADDR_V4MAPPED(&ipp->ipp_addr))
4455                                 v6src = ipp->ipp_addr;
4456                 } else {
4457                         if (!IN6_IS_ADDR_V4MAPPED(&ipp->ipp_addr))
4458                                 v6src = ipp->ipp_addr;
4459                 }
4460         }
4461 
4462         /* Defer IPsec if it might need to look at ICMP type/code */
4463         switch (ixa->ixa_protocol) {
4464         case IPPROTO_ICMP:
4465         case IPPROTO_ICMPV6:
4466                 do_ipsec = B_FALSE;
4467                 break;
4468         default:




   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 (c) 2013 by Delphix. 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/cmn_err.h>
  42 #include <sys/kmem.h>
  43 #include <sys/cred.h>
  44 #include <sys/policy.h>


 752                 dstport = sin->sin_port;
 753                 IN6_IPADDR_TO_V4MAPPED(v4dst, &v6dst);
 754                 ASSERT(connp->conn_ipversion == IPV4_VERSION);
 755                 break;
 756 
 757         case sizeof (sin6_t):
 758                 sin6 = (sin6_t *)sa;
 759 
 760                 /* No support for mapped addresses on raw sockets */
 761                 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
 762                         return (EADDRNOTAVAIL);
 763                 }
 764                 v6dst = sin6->sin6_addr;
 765                 dstport = sin6->sin6_port;
 766                 ASSERT(connp->conn_ipversion == IPV6_VERSION);
 767                 flowinfo = sin6->sin6_flowinfo;
 768                 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
 769                         scopeid = sin6->sin6_scope_id;
 770                 srcid = sin6->__sin6_src_id;
 771                 if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) {
 772                         /* Due to check above, we know sin6_addr is v6-only. */
 773                         if (!ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
 774                             B_FALSE, connp->conn_netstack)) {
 775                                 /* Mismatch - v6src would be v4mapped. */
 776                                 return (EADDRNOTAVAIL);
 777                         }
 778                 }
 779                 break;
 780         }
 781 
 782         /*
 783          * If there is a different thread using conn_ixa then we get a new
 784          * copy and cut the old one loose from conn_ixa. Otherwise we use
 785          * conn_ixa and prevent any other thread from using/changing it.
 786          * Once connect() is done other threads can use conn_ixa since the
 787          * refcnt will be back at one.
 788          * We defer updating conn_ixa until later to handle any concurrent
 789          * conn_ixa_cleanup thread.
 790          */
 791         ixa = conn_get_ixa(connp, B_FALSE);
 792         if (ixa == NULL)
 793                 return (ENOMEM);
 794 
 795         mutex_enter(&connp->conn_lock);
 796         /*
 797          * This icmp_t must have bound already before doing a connect.
 798          * Reject if a connect is in progress (we drop conn_lock during


3325  * Handle T_UNITDATA_REQ with options. Both IPv4 and IPv6
3326  * Either tudr_mp or msg is set. If tudr_mp we take ancillary data from
3327  * the TPI options, otherwise we take them from msg_control.
3328  * If both sin and sin6 is set it is a connected socket and we use conn_faddr.
3329  * Always consumes mp; never consumes tudr_mp.
3330  */
3331 static int
3332 icmp_output_ancillary(conn_t *connp, sin_t *sin, sin6_t *sin6, mblk_t *mp,
3333     mblk_t *tudr_mp, struct nmsghdr *msg, cred_t *cr, pid_t pid)
3334 {
3335         icmp_t          *icmp = connp->conn_icmp;
3336         icmp_stack_t    *is = icmp->icmp_is;
3337         int             error;
3338         ip_xmit_attr_t  *ixa;
3339         ip_pkt_t        *ipp;
3340         in6_addr_t      v6src;
3341         in6_addr_t      v6dst;
3342         in6_addr_t      v6nexthop;
3343         in_port_t       dstport;
3344         uint32_t        flowinfo;

3345         int             is_absreq_failure = 0;
3346         conn_opt_arg_t  coas, *coa;
3347 
3348         ASSERT(tudr_mp != NULL || msg != NULL);
3349 
3350         /*
3351          * Get ixa before checking state to handle a disconnect race.
3352          *
3353          * We need an exclusive copy of conn_ixa since the ancillary data
3354          * options might modify it. That copy has no pointers hence we
3355          * need to set them up once we've parsed the ancillary data.
3356          */
3357         ixa = conn_get_ixa_exclusive(connp);
3358         if (ixa == NULL) {
3359                 BUMP_MIB(&is->is_rawip_mib, rawipOutErrors);
3360                 freemsg(mp);
3361                 return (ENOMEM);
3362         }
3363         ASSERT(cr != NULL);
3364         ASSERT(!(ixa->ixa_free_flags & IXA_FREE_CRED));


3427         ASSERT(is_absreq_failure == 0);
3428 
3429         mutex_enter(&connp->conn_lock);
3430         /*
3431          * If laddr is unspecified then we look at sin6_src_id.
3432          * We will give precedence to a source address set with IPV6_PKTINFO
3433          * (aka IPPF_ADDR) but that is handled in build_hdrs. However, we don't
3434          * want ip_attr_connect to select a source (since it can fail) when
3435          * IPV6_PKTINFO is specified.
3436          * If this doesn't result in a source address then we get a source
3437          * from ip_attr_connect() below.
3438          */
3439         v6src = connp->conn_saddr_v6;
3440         if (sin != NULL) {
3441                 IN6_IPADDR_TO_V4MAPPED(sin->sin_addr.s_addr, &v6dst);
3442                 dstport = sin->sin_port;
3443                 flowinfo = 0;
3444                 ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
3445                 ixa->ixa_flags |= IXAF_IS_IPV4;
3446         } else if (sin6 != NULL) {
3447                 boolean_t v4mapped;
3448                 uint_t srcid;
3449 
3450                 v6dst = sin6->sin6_addr;
3451                 dstport = sin6->sin6_port;
3452                 flowinfo = sin6->sin6_flowinfo;
3453                 srcid = sin6->__sin6_src_id;
3454                 if (IN6_IS_ADDR_LINKSCOPE(&v6dst) && sin6->sin6_scope_id != 0) {
3455                         ixa->ixa_scopeid = sin6->sin6_scope_id;
3456                         ixa->ixa_flags |= IXAF_SCOPEID_SET;
3457                 } else {
3458                         ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
3459                 }
3460                 v4mapped = IN6_IS_ADDR_V4MAPPED(&v6dst);
3461                 if (v4mapped)



3462                         ixa->ixa_flags |= IXAF_IS_IPV4;
3463                 else
3464                         ixa->ixa_flags &= ~IXAF_IS_IPV4;
3465                 if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) {
3466                         if (ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
3467                             v4mapped, connp->conn_netstack)) {
3468                                 /* Mismatched v4mapped/v6 specified by srcid. */
3469                                 mutex_exit(&connp->conn_lock);
3470                                 error = EADDRNOTAVAIL;
3471                                 goto failed;    /* Does freemsg() and mib. */
3472                         }
3473                 }
3474         } else {
3475                 /* Connected case */
3476                 v6dst = connp->conn_faddr_v6;
3477                 flowinfo = connp->conn_flowinfo;
3478         }
3479         mutex_exit(&connp->conn_lock);
3480         /* Handle IP_PKTINFO/IPV6_PKTINFO setting source address. */
3481         if (ipp->ipp_fields & IPPF_ADDR) {
3482                 if (ixa->ixa_flags & IXAF_IS_IPV4) {
3483                         if (IN6_IS_ADDR_V4MAPPED(&ipp->ipp_addr))
3484                                 v6src = ipp->ipp_addr;
3485                 } else {
3486                         if (!IN6_IS_ADDR_V4MAPPED(&ipp->ipp_addr))
3487                                 v6src = ipp->ipp_addr;
3488                 }
3489         }
3490         /*
3491          * Allow source not assigned to the system
3492          * only if it is not a local addresses
3493          */


4415                 goto ud_error;
4416         }
4417 
4418         /* In case previous destination was multicast or multirt */
4419         ip_attr_newdst(ixa);
4420 
4421         /*
4422          * If laddr is unspecified then we look at sin6_src_id.
4423          * We will give precedence to a source address set with IPV6_PKTINFO
4424          * (aka IPPF_ADDR) but that is handled in build_hdrs. However, we don't
4425          * want ip_attr_connect to select a source (since it can fail) when
4426          * IPV6_PKTINFO is specified.
4427          * If this doesn't result in a source address then we get a source
4428          * from ip_attr_connect() below.
4429          */
4430         v6src = connp->conn_saddr_v6;
4431         if (sin != NULL) {
4432                 IN6_IPADDR_TO_V4MAPPED(sin->sin_addr.s_addr, &v6dst);
4433                 dstport = sin->sin_port;
4434                 flowinfo = 0;
4435                 /* Don't bother with ip_srcid_find_id(), but indicate anyway. */
4436                 srcid = 0;
4437                 ixa->ixa_flags &= ~IXAF_SCOPEID_SET;




4438                 ixa->ixa_flags |= IXAF_IS_IPV4;
4439         } else {
4440                 boolean_t v4mapped;
4441 
4442                 v6dst = sin6->sin6_addr;
4443                 dstport = sin6->sin6_port;
4444                 flowinfo = sin6->sin6_flowinfo;
4445                 srcid = sin6->__sin6_src_id;
4446                 if (IN6_IS_ADDR_LINKSCOPE(&v6dst) && sin6->sin6_scope_id != 0) {
4447                         ixa->ixa_scopeid = sin6->sin6_scope_id;
4448                         ixa->ixa_flags |= IXAF_SCOPEID_SET;
4449                 } else {
4450                         ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
4451                 }
4452                 v4mapped = IN6_IS_ADDR_V4MAPPED(&v6dst);
4453                 if (v4mapped)



4454                         ixa->ixa_flags |= IXAF_IS_IPV4;
4455                 else
4456                         ixa->ixa_flags &= ~IXAF_IS_IPV4;
4457                 if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) {
4458                         if (ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
4459                             v4mapped, connp->conn_netstack)) {
4460                                 /* Mismatched v4mapped/v6 specified by srcid. */
4461                                 mutex_exit(&connp->conn_lock);
4462                                 error = EADDRNOTAVAIL;
4463                                 goto ud_error;
4464                         }
4465                 }
4466         }
4467         /* Handle IP_PKTINFO/IPV6_PKTINFO setting source address. */
4468         if (connp->conn_xmit_ipp.ipp_fields & IPPF_ADDR) {
4469                 ip_pkt_t *ipp = &connp->conn_xmit_ipp;
4470 
4471                 if (ixa->ixa_flags & IXAF_IS_IPV4) {
4472                         if (IN6_IS_ADDR_V4MAPPED(&ipp->ipp_addr))
4473                                 v6src = ipp->ipp_addr;
4474                 } else {
4475                         if (!IN6_IS_ADDR_V4MAPPED(&ipp->ipp_addr))
4476                                 v6src = ipp->ipp_addr;
4477                 }
4478         }
4479 
4480         /* Defer IPsec if it might need to look at ICMP type/code */
4481         switch (ixa->ixa_protocol) {
4482         case IPPROTO_ICMP:
4483         case IPPROTO_ICMPV6:
4484                 do_ipsec = B_FALSE;
4485                 break;
4486         default: