Home | History | Annotate | Download | only in ip
      1      0      stevel /*
      2      0      stevel  * CDDL HEADER START
      3      0      stevel  *
      4      0      stevel  * The contents of this file are subject to the terms of the
      5   1659     markfen  * Common Development and Distribution License (the "License").
      6   1659     markfen  * You may not use this file except in compliance with the License.
      7      0      stevel  *
      8      0      stevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9      0      stevel  * or http://www.opensolaris.org/os/licensing.
     10      0      stevel  * See the License for the specific language governing permissions
     11      0      stevel  * and limitations under the License.
     12      0      stevel  *
     13      0      stevel  * When distributing Covered Code, include this CDDL HEADER in each
     14      0      stevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15      0      stevel  * If applicable, add the following below this CDDL HEADER, with the
     16      0      stevel  * fields enclosed by brackets "[]" replaced with your own identifying
     17      0      stevel  * information: Portions Copyright [yyyy] [name of copyright owner]
     18      0      stevel  *
     19      0      stevel  * CDDL HEADER END
     20      0      stevel  */
     21      0      stevel /*
     22   8485       Peter  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23      0      stevel  * Use is subject to license terms.
     24      0      stevel  */
     25      0      stevel 
     26      0      stevel /*
     27      0      stevel  * IPsec Security Policy Database.
     28      0      stevel  *
     29      0      stevel  * This module maintains the SPD and provides routines used by ip and ip6
     30      0      stevel  * to apply IPsec policy to inbound and outbound datagrams.
     31      0      stevel  */
     32      0      stevel 
     33      0      stevel #include <sys/types.h>
     34      0      stevel #include <sys/stream.h>
     35      0      stevel #include <sys/stropts.h>
     36      0      stevel #include <sys/sysmacros.h>
     37      0      stevel #include <sys/strsubr.h>
     38  10934  sommerfeld #include <sys/strsun.h>
     39      0      stevel #include <sys/strlog.h>
     40  11042        Erik #include <sys/strsun.h>
     41      0      stevel #include <sys/cmn_err.h>
     42      0      stevel #include <sys/zone.h>
     43      0      stevel 
     44      0      stevel #include <sys/systm.h>
     45      0      stevel #include <sys/param.h>
     46      0      stevel #include <sys/kmem.h>
     47   3055      danmcd #include <sys/ddi.h>
     48      0      stevel 
     49      0      stevel #include <sys/crypto/api.h>
     50      0      stevel 
     51      0      stevel #include <inet/common.h>
     52      0      stevel #include <inet/mi.h>
     53      0      stevel 
     54      0      stevel #include <netinet/ip6.h>
     55      0      stevel #include <netinet/icmp6.h>
     56      0      stevel #include <netinet/udp.h>
     57      0      stevel 
     58      0      stevel #include <inet/ip.h>
     59      0      stevel #include <inet/ip6.h>
     60      0      stevel 
     61      0      stevel #include <net/pfkeyv2.h>
     62      0      stevel #include <net/pfpolicy.h>
     63      0      stevel #include <inet/sadb.h>
     64      0      stevel #include <inet/ipsec_impl.h>
     65   3192      danmcd 
     66   3192      danmcd #include <inet/ip_impl.h>	/* For IP_MOD_ID */
     67   3192      danmcd 
     68      0      stevel #include <inet/ipsecah.h>
     69      0      stevel #include <inet/ipsecesp.h>
     70      0      stevel #include <inet/ipdrop.h>
     71      0      stevel #include <inet/ipclassifier.h>
     72  10616   Sebastien #include <inet/iptun.h>
     73  10616   Sebastien #include <inet/iptun/iptun_impl.h>
     74      0      stevel 
     75   3448    dh155122 static void ipsec_update_present_flags(ipsec_stack_t *);
     76   3448    dh155122 static ipsec_act_t *ipsec_act_wildcard_expand(ipsec_act_t *, uint_t *,
     77   3448    dh155122     netstack_t *);
     78   3192      danmcd static mblk_t *ipsec_check_ipsecin_policy(mblk_t *, ipsec_policy_t *,
     79  11042        Erik     ipha_t *, ip6_t *, uint64_t, ip_recv_attr_t *, netstack_t *);
     80   3448    dh155122 static void ipsec_action_free_table(ipsec_action_t *);
     81      0      stevel static void ipsec_action_reclaim(void *);
     82   3448    dh155122 static void ipsec_action_reclaim_stack(netstack_t *);
     83   3448    dh155122 static void ipsid_init(netstack_t *);
     84   3448    dh155122 static void ipsid_fini(netstack_t *);
     85   3055      danmcd 
     86   3055      danmcd /* sel_flags values for ipsec_init_inbound_sel(). */
     87   3055      danmcd #define	SEL_NONE	0x0000
     88   3055      danmcd #define	SEL_PORT_POLICY	0x0001
     89   3055      danmcd #define	SEL_IS_ICMP	0x0002
     90   3055      danmcd #define	SEL_TUNNEL_MODE	0x0004
     91  10616   Sebastien #define	SEL_POST_FRAG	0x0008
     92   3055      danmcd 
     93   3055      danmcd /* Return values for ipsec_init_inbound_sel(). */
     94   3055      danmcd typedef enum { SELRET_NOMEM, SELRET_BADPKT, SELRET_SUCCESS, SELRET_TUNFRAG}
     95   3055      danmcd     selret_t;
     96   3055      danmcd 
     97   3055      danmcd static selret_t ipsec_init_inbound_sel(ipsec_selector_t *, mblk_t *,
     98   3055      danmcd     ipha_t *, ip6_t *, uint8_t);
     99   3055      danmcd 
    100  11042        Erik static boolean_t ipsec_check_ipsecin_action(ip_recv_attr_t *, mblk_t *,
    101      0      stevel     struct ipsec_action_s *, ipha_t *ipha, ip6_t *ip6h, const char **,
    102  11042        Erik     kstat_named_t **, netstack_t *);
    103      0      stevel static void ipsec_unregister_prov_update(void);
    104   3448    dh155122 static void ipsec_prov_update_callback_stack(uint32_t, void *, netstack_t *);
    105     81    sommerfe static boolean_t ipsec_compare_action(ipsec_policy_t *, ipsec_policy_t *);
    106   3055      danmcd static uint32_t selector_hash(ipsec_selector_t *, ipsec_policy_root_t *);
    107   3448    dh155122 static boolean_t ipsec_kstat_init(ipsec_stack_t *);
    108   3448    dh155122 static void ipsec_kstat_destroy(ipsec_stack_t *);
    109   3448    dh155122 static int ipsec_free_tables(ipsec_stack_t *);
    110   3055      danmcd static int tunnel_compare(const void *, const void *);
    111   3055      danmcd static void ipsec_freemsg_chain(mblk_t *);
    112  11042        Erik static void ip_drop_packet_chain(mblk_t *, boolean_t, ill_t *,
    113   3055      danmcd     struct kstat_named *, ipdropper_t *);
    114   3448    dh155122 static boolean_t ipsec_kstat_init(ipsec_stack_t *);
    115   3448    dh155122 static void ipsec_kstat_destroy(ipsec_stack_t *);
    116   3448    dh155122 static int ipsec_free_tables(ipsec_stack_t *);
    117   3448    dh155122 static int tunnel_compare(const void *, const void *);
    118   3448    dh155122 static void ipsec_freemsg_chain(mblk_t *);
    119     81    sommerfe 
    120     81    sommerfe /*
    121     81    sommerfe  * Selector hash table is statically sized at module load time.
    122     81    sommerfe  * we default to 251 buckets, which is the largest prime number under 255
    123     81    sommerfe  */
    124     81    sommerfe 
    125     81    sommerfe #define	IPSEC_SPDHASH_DEFAULT 251
    126   3055      danmcd 
    127   3055      danmcd /* SPD hash-size tunable per tunnel. */
    128   3055      danmcd #define	TUN_SPDHASH_DEFAULT 5
    129   3055      danmcd 
    130   5245      danmcd uint32_t ipsec_spd_hashsize;
    131   5245      danmcd uint32_t tun_spd_hashsize;
    132     81    sommerfe 
    133     81    sommerfe #define	IPSEC_SEL_NOHASH ((uint32_t)(~0))
    134      0      stevel 
    135   3448    dh155122 /*
    136   3448    dh155122  * Handle global across all stack instances
    137   3448    dh155122  */
    138   3448    dh155122 static crypto_notify_handle_t prov_update_handle = NULL;
    139     81    sommerfe 
    140      0      stevel static kmem_cache_t *ipsec_action_cache;
    141      0      stevel static kmem_cache_t *ipsec_sel_cache;
    142      0      stevel static kmem_cache_t *ipsec_pol_cache;
    143      0      stevel 
    144   3055      danmcd /* Frag cache prototypes */
    145  11042        Erik static void ipsec_fragcache_clean(ipsec_fragcache_t *, ipsec_stack_t *);
    146   3055      danmcd static ipsec_fragcache_entry_t *fragcache_delentry(int,
    147  11042        Erik     ipsec_fragcache_entry_t *, ipsec_fragcache_t *, ipsec_stack_t *);
    148   3055      danmcd boolean_t ipsec_fragcache_init(ipsec_fragcache_t *);
    149  11042        Erik void ipsec_fragcache_uninit(ipsec_fragcache_t *, ipsec_stack_t *ipss);
    150  11042        Erik mblk_t *ipsec_fragcache_add(ipsec_fragcache_t *, mblk_t *, mblk_t *,
    151  11042        Erik     int, ipsec_stack_t *);
    152      0      stevel 
    153    691    sommerfe int ipsec_hdr_pullup_needed = 0;
    154    691    sommerfe int ipsec_weird_null_inbound_policy = 0;
    155    691    sommerfe 
    156      0      stevel #define	ALGBITS_ROUND_DOWN(x, align)	(((x)/(align))*(align))
    157      0      stevel #define	ALGBITS_ROUND_UP(x, align)	ALGBITS_ROUND_DOWN((x)+(align)-1, align)
    158      0      stevel 
    159      0      stevel /*
    160      0      stevel  * Inbound traffic should have matching identities for both SA's.
    161      0      stevel  */
    162      0      stevel 
    163      0      stevel #define	SA_IDS_MATCH(sa1, sa2) 						\
    164      0      stevel 	(((sa1) == NULL) || ((sa2) == NULL) ||				\
    165      0      stevel 	(((sa1)->ipsa_src_cid == (sa2)->ipsa_src_cid) &&		\
    166      0      stevel 	    (((sa1)->ipsa_dst_cid == (sa2)->ipsa_dst_cid))))
    167   3055      danmcd 
    168   3055      danmcd /*
    169   3055      danmcd  * IPv6 Fragments
    170   3055      danmcd  */
    171   3055      danmcd #define	IS_V6_FRAGMENT(ipp)	(ipp.ipp_fields & IPPF_FRAGHDR)
    172     81    sommerfe 
    173      0      stevel /*
    174      0      stevel  * Policy failure messages.
    175      0      stevel  */
    176      0      stevel static char *ipsec_policy_failure_msgs[] = {
    177      0      stevel 
    178      0      stevel 	/* IPSEC_POLICY_NOT_NEEDED */
    179      0      stevel 	"%s: Dropping the datagram because the incoming packet "
    180      0      stevel 	"is %s, but the recipient expects clear; Source %s, "
    181      0      stevel 	"Destination %s.\n",
    182      0      stevel 
    183      0      stevel 	/* IPSEC_POLICY_MISMATCH */
    184      0      stevel 	"%s: Policy Failure for the incoming packet (%s); Source %s, "
    185      0      stevel 	"Destination %s.\n",
    186      0      stevel 
    187      0      stevel 	/* IPSEC_POLICY_AUTH_NOT_NEEDED	*/
    188      0      stevel 	"%s: Authentication present while not expected in the "
    189      0      stevel 	"incoming %s packet; Source %s, Destination %s.\n",
    190      0      stevel 
    191      0      stevel 	/* IPSEC_POLICY_ENCR_NOT_NEEDED */
    192      0      stevel 	"%s: Encryption present while not expected in the "
    193      0      stevel 	"incoming %s packet; Source %s, Destination %s.\n",
    194      0      stevel 
    195      0      stevel 	/* IPSEC_POLICY_SE_NOT_NEEDED */
    196      0      stevel 	"%s: Self-Encapsulation present while not expected in the "
    197      0      stevel 	"incoming %s packet; Source %s, Destination %s.\n",
    198      0      stevel };
    199      0      stevel 
    200      0      stevel /*
    201      0      stevel  * General overviews:
    202      0      stevel  *
    203      0      stevel  * Locking:
    204      0      stevel  *
    205      0      stevel  *	All of the system policy structures are protected by a single
    206   3448    dh155122  *	rwlock.  These structures are threaded in a
    207      0      stevel  *	fairly complex fashion and are not expected to change on a
    208      0      stevel  *	regular basis, so this should not cause scaling/contention
    209      0      stevel  *	problems.  As a result, policy checks should (hopefully) be MT-hot.
    210      0      stevel  *
    211      0      stevel  * Allocation policy:
    212      0      stevel  *
    213      0      stevel  *	We use custom kmem cache types for the various
    214      0      stevel  *	bits & pieces of the policy data structures.  All allocations
    215      0      stevel  *	use KM_NOSLEEP instead of KM_SLEEP for policy allocation.  The
    216      0      stevel  *	policy table is of potentially unbounded size, so we don't
    217      0      stevel  *	want to provide a way to hog all system memory with policy
    218      0      stevel  *	entries..
    219      0      stevel  */
    220      0      stevel 
    221   3055      danmcd /* Convenient functions for freeing or dropping a b_next linked mblk chain */
    222   3055      danmcd 
    223   3055      danmcd /* Free all messages in an mblk chain */
    224   3055      danmcd static void
    225   3055      danmcd ipsec_freemsg_chain(mblk_t *mp)
    226   3055      danmcd {
    227   3055      danmcd 	mblk_t *mpnext;
    228   3055      danmcd 	while (mp != NULL) {
    229   3055      danmcd 		ASSERT(mp->b_prev == NULL);
    230   3055      danmcd 		mpnext = mp->b_next;
    231   3055      danmcd 		mp->b_next = NULL;
    232  11042        Erik 		freemsg(mp);
    233   3055      danmcd 		mp = mpnext;
    234   3055      danmcd 	}
    235   3055      danmcd }
    236   3055      danmcd 
    237  11042        Erik /*
    238  11042        Erik  * ip_drop all messages in an mblk chain
    239  11042        Erik  * Can handle a b_next chain of ip_recv_attr_t mblks, or just a b_next chain
    240  11042        Erik  * of data.
    241  11042        Erik  */
    242  11042        Erik static void
    243  11042        Erik ip_drop_packet_chain(mblk_t *mp, boolean_t inbound, ill_t *ill,
    244  11042        Erik     struct kstat_named *counter, ipdropper_t *who_called)
    245   3055      danmcd {
    246   3055      danmcd 	mblk_t *mpnext;
    247   3055      danmcd 	while (mp != NULL) {
    248   3055      danmcd 		ASSERT(mp->b_prev == NULL);
    249   3055      danmcd 		mpnext = mp->b_next;
    250   3055      danmcd 		mp->b_next = NULL;
    251  11042        Erik 		if (ip_recv_attr_is_mblk(mp))
    252  11042        Erik 			mp = ip_recv_attr_free_mblk(mp);
    253  11042        Erik 		ip_drop_packet(mp, inbound, ill, counter, who_called);
    254   3055      danmcd 		mp = mpnext;
    255   3055      danmcd 	}
    256   3055      danmcd }
    257     81    sommerfe 
    258     81    sommerfe /*
    259     81    sommerfe  * AVL tree comparison function.
    260     81    sommerfe  * the in-kernel avl assumes unique keys for all objects.
    261     81    sommerfe  * Since sometimes policy will duplicate rules, we may insert
    262     81    sommerfe  * multiple rules with the same rule id, so we need a tie-breaker.
    263     81    sommerfe  */
    264     81    sommerfe static int
    265     81    sommerfe ipsec_policy_cmpbyid(const void *a, const void *b)
    266     81    sommerfe {
    267     81    sommerfe 	const ipsec_policy_t *ipa, *ipb;
    268     81    sommerfe 	uint64_t idxa, idxb;
    269     81    sommerfe 
    270     81    sommerfe 	ipa = (const ipsec_policy_t *)a;
    271     81    sommerfe 	ipb = (const ipsec_policy_t *)b;
    272     81    sommerfe 	idxa = ipa->ipsp_index;
    273     81    sommerfe 	idxb = ipb->ipsp_index;
    274     81    sommerfe 
    275     81    sommerfe 	if (idxa < idxb)
    276     81    sommerfe 		return (-1);
    277     81    sommerfe 	if (idxa > idxb)
    278     81    sommerfe 		return (1);
    279     81    sommerfe 	/*
    280     81    sommerfe 	 * Tie-breaker #1: All installed policy rules have a non-NULL
    281     81    sommerfe 	 * ipsl_sel (selector set), so an entry with a NULL ipsp_sel is not
    282     81    sommerfe 	 * actually in-tree but rather a template node being used in
    283     81    sommerfe 	 * an avl_find query; see ipsec_policy_delete().  This gives us
    284  11042        Erik 	 * a placeholder in the ordering just before the first entry with
    285     81    sommerfe 	 * a key >= the one we're looking for, so we can walk forward from
    286     81    sommerfe 	 * that point to get the remaining entries with the same id.
    287     81    sommerfe 	 */
    288     81    sommerfe 	if ((ipa->ipsp_sel == NULL) && (ipb->ipsp_sel != NULL))
    289     81    sommerfe 		return (-1);
    290     81    sommerfe 	if ((ipb->ipsp_sel == NULL) && (ipa->ipsp_sel != NULL))
    291     81    sommerfe 		return (1);
    292     81    sommerfe 	/*
    293     81    sommerfe 	 * At most one of the arguments to the comparison should have a
    294     81    sommerfe 	 * NULL selector pointer; if not, the tree is broken.
    295     81    sommerfe 	 */
    296     81    sommerfe 	ASSERT(ipa->ipsp_sel != NULL);
    297     81    sommerfe 	ASSERT(ipb->ipsp_sel != NULL);
    298     81    sommerfe 	/*
    299     81    sommerfe 	 * Tie-breaker #2: use the virtual address of the policy node
    300     81    sommerfe 	 * to arbitrarily break ties.  Since we use the new tree node in
    301     81    sommerfe 	 * the avl_find() in ipsec_insert_always, the new node will be
    302     81    sommerfe 	 * inserted into the tree in the right place in the sequence.
    303     81    sommerfe 	 */
    304     81    sommerfe 	if (ipa < ipb)
    305     81    sommerfe 		return (-1);
    306     81    sommerfe 	if (ipa > ipb)
    307     81    sommerfe 		return (1);
    308     81    sommerfe 	return (0);
    309     81    sommerfe }
    310     81    sommerfe 
    311   3448    dh155122 /*
    312   3448    dh155122  * Free what ipsec_alloc_table allocated.
    313   3448    dh155122  */
    314   3055      danmcd void
    315     81    sommerfe ipsec_polhead_free_table(ipsec_policy_head_t *iph)
    316     81    sommerfe {
    317   3055      danmcd 	int dir;
    318   3448    dh155122 	int i;
    319     81    sommerfe 
    320     81    sommerfe 	for (dir = 0; dir < IPSEC_NTYPES; dir++) {
    321     81    sommerfe 		ipsec_policy_root_t *ipr = &iph->iph_root[dir];
    322     81    sommerfe 
    323     81    sommerfe 		if (ipr->ipr_hash == NULL)
    324     81    sommerfe 			continue;
    325     81    sommerfe 
    326   3448    dh155122 		for (i = 0; i < ipr->ipr_nchains; i++) {
    327   3448    dh155122 			ASSERT(ipr->ipr_hash[i].hash_head == NULL);
    328   3448    dh155122 		}
    329   3055      danmcd 		kmem_free(ipr->ipr_hash, ipr->ipr_nchains *
    330     81    sommerfe 		    sizeof (ipsec_policy_hash_t));
    331   3448    dh155122 		ipr->ipr_hash = NULL;
    332     81    sommerfe 	}
    333     81    sommerfe }
    334     81    sommerfe 
    335   3055      danmcd void
    336     81    sommerfe ipsec_polhead_destroy(ipsec_policy_head_t *iph)
    337     81    sommerfe {
    338     81    sommerfe 	int dir;
    339     81    sommerfe 
    340     81    sommerfe 	avl_destroy(&iph->iph_rulebyid);
    341     81    sommerfe 	rw_destroy(&iph->iph_lock);
    342     81    sommerfe 
    343     81    sommerfe 	for (dir = 0; dir < IPSEC_NTYPES; dir++) {
    344     81    sommerfe 		ipsec_policy_root_t *ipr = &iph->iph_root[dir];
    345     81    sommerfe 		int chain;
    346     81    sommerfe 
    347   3055      danmcd 		for (chain = 0; chain < ipr->ipr_nchains; chain++)
    348     81    sommerfe 			mutex_destroy(&(ipr->ipr_hash[chain].hash_lock));
    349     81    sommerfe 
    350     81    sommerfe 	}
    351     81    sommerfe 	ipsec_polhead_free_table(iph);
    352     81    sommerfe }
    353     81    sommerfe 
    354      0      stevel /*
    355   3448    dh155122  * Free the IPsec stack instance.
    356   3448    dh155122  */
    357   3448    dh155122 /* ARGSUSED */
    358   3448    dh155122 static void
    359   3448    dh155122 ipsec_stack_fini(netstackid_t stackid, void *arg)
    360   3448    dh155122 {
    361   3448    dh155122 	ipsec_stack_t	*ipss = (ipsec_stack_t *)arg;
    362   3055      danmcd 	void *cookie;
    363   3055      danmcd 	ipsec_tun_pol_t *node;
    364   3448    dh155122 	netstack_t	*ns = ipss->ipsec_netstack;
    365   3448    dh155122 	int		i;
    366   3448    dh155122 	ipsec_algtype_t	algtype;
    367   3448    dh155122 
    368   3448    dh155122 	ipsec_loader_destroy(ipss);
    369   3448    dh155122 
    370   3448    dh155122 	rw_enter(&ipss->ipsec_tunnel_policy_lock, RW_WRITER);
    371   3055      danmcd 	/*
    372   3055      danmcd 	 * It's possible we can just ASSERT() the tree is empty.  After all,
    373   3055      danmcd 	 * we aren't called until IP is ready to unload (and presumably all
    374   3055      danmcd 	 * tunnels have been unplumbed).  But we'll play it safe for now, the
    375   3055      danmcd 	 * loop will just exit immediately if it's empty.
    376   3055      danmcd 	 */
    377   3055      danmcd 	cookie = NULL;
    378   3055      danmcd 	while ((node = (ipsec_tun_pol_t *)
    379   3448    dh155122 	    avl_destroy_nodes(&ipss->ipsec_tunnel_policies,
    380   3448    dh155122 	    &cookie)) != NULL) {
    381   3448    dh155122 		ITP_REFRELE(node, ns);
    382   3448    dh155122 	}
    383   3448    dh155122 	avl_destroy(&ipss->ipsec_tunnel_policies);
    384   3448    dh155122 	rw_exit(&ipss->ipsec_tunnel_policy_lock);
    385   3448    dh155122 	rw_destroy(&ipss->ipsec_tunnel_policy_lock);
    386   3448    dh155122 
    387   3448    dh155122 	ipsec_config_flush(ns);
    388   3448    dh155122 
    389   3448    dh155122 	ipsec_kstat_destroy(ipss);
    390   3448    dh155122 
    391   3448    dh155122 	ip_drop_unregister(&ipss->ipsec_dropper);
    392   3448    dh155122 
    393   3448    dh155122 	ip_drop_unregister(&ipss->ipsec_spd_dropper);
    394   3448    dh155122 	ip_drop_destroy(ipss);
    395   3448    dh155122 	/*
    396   3448    dh155122 	 * Globals start with ref == 1 to prevent IPPH_REFRELE() from
    397   3448    dh155122 	 * attempting to free them, hence they should have 1 now.
    398   3448    dh155122 	 */
    399   3448    dh155122 	ipsec_polhead_destroy(&ipss->ipsec_system_policy);
    400   3448    dh155122 	ASSERT(ipss->ipsec_system_policy.iph_refs == 1);
    401   3448    dh155122 	ipsec_polhead_destroy(&ipss->ipsec_inactive_policy);
    402   3448    dh155122 	ASSERT(ipss->ipsec_inactive_policy.iph_refs == 1);
    403   3448    dh155122 
    404   3448    dh155122 	for (i = 0; i < IPSEC_ACTION_HASH_SIZE; i++) {
    405   3448    dh155122 		ipsec_action_free_table(ipss->ipsec_action_hash[i].hash_head);
    406   3448    dh155122 		ipss->ipsec_action_hash[i].hash_head = NULL;
    407   3448    dh155122 		mutex_destroy(&(ipss->ipsec_action_hash[i].hash_lock));
    408   3448    dh155122 	}
    409   3448    dh155122 
    410   3448    dh155122 	for (i = 0; i < ipss->ipsec_spd_hashsize; i++) {
    411   3448    dh155122 		ASSERT(ipss->ipsec_sel_hash[i].hash_head == NULL);
    412   3448    dh155122 		mutex_destroy(&(ipss->ipsec_sel_hash[i].hash_lock));
    413   3448    dh155122 	}
    414   3448    dh155122 
    415   3448    dh155122 	mutex_enter(&ipss->ipsec_alg_lock);
    416   3448    dh155122 	for (algtype = 0; algtype < IPSEC_NALGTYPES; algtype ++) {
    417   3448    dh155122 		int nalgs = ipss->ipsec_nalgs[algtype];
    418   3448    dh155122 
    419   3448    dh155122 		for (i = 0; i < nalgs; i++) {
    420   3448    dh155122 			if (ipss->ipsec_alglists[algtype][i] != NULL)
    421   3448    dh155122 				ipsec_alg_unreg(algtype, i, ns);
    422   3448    dh155122 		}
    423   3448    dh155122 	}
    424   3448    dh155122 	mutex_exit(&ipss->ipsec_alg_lock);
    425   3448    dh155122 	mutex_destroy(&ipss->ipsec_alg_lock);
    426   3448    dh155122 
    427   3448    dh155122 	ipsid_gc(ns);
    428   3448    dh155122 	ipsid_fini(ns);
    429   3448    dh155122 
    430   3448    dh155122 	(void) ipsec_free_tables(ipss);
    431   3448    dh155122 	kmem_free(ipss, sizeof (*ipss));
    432   3448    dh155122 }
    433   3448    dh155122 
    434   3448    dh155122 void
    435   3448    dh155122 ipsec_policy_g_destroy(void)
    436   3448    dh155122 {
    437      0      stevel 	kmem_cache_destroy(ipsec_action_cache);
    438      0      stevel 	kmem_cache_destroy(ipsec_sel_cache);
    439      0      stevel 	kmem_cache_destroy(ipsec_pol_cache);
    440   3448    dh155122 
    441   3448    dh155122 	ipsec_unregister_prov_update();
    442   3448    dh155122 
    443   3448    dh155122 	netstack_unregister(NS_IPSEC);
    444   3448    dh155122 }
    445   3448    dh155122 
    446   3448    dh155122 
    447   3448    dh155122 /*
    448   3448    dh155122  * Free what ipsec_alloc_tables allocated.
    449     81    sommerfe  * Called when table allocation fails to free the table.
    450     81    sommerfe  */
    451     81    sommerfe static int
    452   3448    dh155122 ipsec_free_tables(ipsec_stack_t *ipss)
    453   3448    dh155122 {
    454   3448    dh155122 	int i;
    455   3448    dh155122 
    456   3448    dh155122 	if (ipss->ipsec_sel_hash != NULL) {
    457   3448    dh155122 		for (i = 0; i < ipss->ipsec_spd_hashsize; i++) {
    458   3448    dh155122 			ASSERT(ipss->ipsec_sel_hash[i].hash_head == NULL);
    459   3448    dh155122 		}
    460   3448    dh155122 		kmem_free(ipss->ipsec_sel_hash, ipss->ipsec_spd_hashsize *
    461   3448    dh155122 		    sizeof (*ipss->ipsec_sel_hash));
    462   3448    dh155122 		ipss->ipsec_sel_hash = NULL;
    463   3448    dh155122 		ipss->ipsec_spd_hashsize = 0;
    464   3448    dh155122 	}
    465   3448    dh155122 	ipsec_polhead_free_table(&ipss->ipsec_system_policy);
    466   3448    dh155122 	ipsec_polhead_free_table(&ipss->ipsec_inactive_policy);
    467     81    sommerfe 
    468     81    sommerfe 	return (ENOMEM);
    469     81    sommerfe }
    470     81    sommerfe 
    471     81    sommerfe /*
    472     81    sommerfe  * Attempt to allocate the tables in a single policy head.
    473     81    sommerfe  * Return nonzero on failure after cleaning up any work in progress.
    474     81    sommerfe  */
    475   3055      danmcd int
    476   3055      danmcd ipsec_alloc_table(ipsec_policy_head_t *iph, int nchains, int kmflag,
    477   3448    dh155122     boolean_t global_cleanup, netstack_t *ns)
    478   3055      danmcd {
    479   3055      danmcd 	int dir;
    480     81    sommerfe 
    481     81    sommerfe 	for (dir = 0; dir < IPSEC_NTYPES; dir++) {
    482     81    sommerfe 		ipsec_policy_root_t *ipr = &iph->iph_root[dir];
    483     81    sommerfe 
    484   3055      danmcd 		ipr->ipr_nchains = nchains;
    485     81    sommerfe 		ipr->ipr_hash = kmem_zalloc(nchains *
    486     81    sommerfe 		    sizeof (ipsec_policy_hash_t), kmflag);
    487     81    sommerfe 		if (ipr->ipr_hash == NULL)
    488   3448    dh155122 			return (global_cleanup ?
    489   3448    dh155122 			    ipsec_free_tables(ns->netstack_ipsec) :
    490   3055      danmcd 			    ENOMEM);
    491     81    sommerfe 	}
    492     81    sommerfe 	return (0);
    493     81    sommerfe }
    494     81    sommerfe 
    495     81    sommerfe /*
    496     81    sommerfe  * Attempt to allocate the various tables.  Return nonzero on failure
    497     81    sommerfe  * after cleaning up any work in progress.
    498     81    sommerfe  */
    499     81    sommerfe static int
    500   3448    dh155122 ipsec_alloc_tables(int kmflag, netstack_t *ns)
    501     81    sommerfe {
    502     81    sommerfe 	int error;
    503   3448    dh155122 	ipsec_stack_t	*ipss = ns->netstack_ipsec;
    504   3448    dh155122 
    505   3448    dh155122 	error = ipsec_alloc_table(&ipss->ipsec_system_policy,
    506   3448    dh155122 	    ipss->ipsec_spd_hashsize, kmflag, B_TRUE, ns);
    507     81    sommerfe 	if (error != 0)
    508     81    sommerfe 		return (error);
    509     81    sommerfe 
    510   3448    dh155122 	error = ipsec_alloc_table(&ipss->ipsec_inactive_policy,
    511   3448    dh155122 	    ipss->ipsec_spd_hashsize, kmflag, B_TRUE, ns);
    512     81    sommerfe 	if (error != 0)
    513     81    sommerfe 		return (error);
    514     81    sommerfe 
    515   3448    dh155122 	ipss->ipsec_sel_hash = kmem_zalloc(ipss->ipsec_spd_hashsize *
    516   3448    dh155122 	    sizeof (*ipss->ipsec_sel_hash), kmflag);
    517   3448    dh155122 
    518   3448    dh155122 	if (ipss->ipsec_sel_hash == NULL)
    519   3448    dh155122 		return (ipsec_free_tables(ipss));
    520     81    sommerfe 
    521     81    sommerfe 	return (0);
    522     81    sommerfe }
    523     81    sommerfe 
    524     81    sommerfe /*
    525     81    sommerfe  * After table allocation, initialize a policy head.
    526     81    sommerfe  */
    527   3055      danmcd void
    528   3055      danmcd ipsec_polhead_init(ipsec_policy_head_t *iph, int nchains)
    529   3055      danmcd {
    530   3055      danmcd 	int dir, chain;
    531     81    sommerfe 
    532     81    sommerfe 	rw_init(&iph->iph_lock, NULL, RW_DEFAULT, NULL);
    533     81    sommerfe 	avl_create(&iph->iph_rulebyid, ipsec_policy_cmpbyid,
    534     81    sommerfe 	    sizeof (ipsec_policy_t), offsetof(ipsec_policy_t, ipsp_byid));
    535     81    sommerfe 
    536     81    sommerfe 	for (dir = 0; dir < IPSEC_NTYPES; dir++) {
    537     81    sommerfe 		ipsec_policy_root_t *ipr = &iph->iph_root[dir];
    538     81    sommerfe 		ipr->ipr_nchains = nchains;
    539     81    sommerfe 
    540     81    sommerfe 		for (chain = 0; chain < nchains; chain++) {
    541     81    sommerfe 			mutex_init(&(ipr->ipr_hash[chain].hash_lock),
    542     81    sommerfe 			    NULL, MUTEX_DEFAULT, NULL);
    543     81    sommerfe 		}
    544     81    sommerfe 	}
    545     81    sommerfe }
    546     81    sommerfe 
    547   3448    dh155122 static boolean_t
    548   3448    dh155122 ipsec_kstat_init(ipsec_stack_t *ipss)
    549   3448    dh155122 {
    550   3448    dh155122 	ipss->ipsec_ksp = kstat_create_netstack("ip", 0, "ipsec_stat", "net",
    551   3448    dh155122 	    KSTAT_TYPE_NAMED, sizeof (ipsec_kstats_t) / sizeof (kstat_named_t),
    552   3448    dh155122 	    KSTAT_FLAG_PERSISTENT, ipss->ipsec_netstack->netstack_stackid);
    553   3448    dh155122 
    554   3448    dh155122 	if (ipss->ipsec_ksp == NULL || ipss->ipsec_ksp->ks_data == NULL)
    555   3448    dh155122 		return (B_FALSE);
    556   3448    dh155122 
    557   3448    dh155122 	ipss->ipsec_kstats = ipss->ipsec_ksp->ks_data;
    558   3448    dh155122 
    559   3448    dh155122 #define	KI(x) kstat_named_init(&ipss->ipsec_kstats->x, #x, KSTAT_DATA_UINT64)
    560   3448    dh155122 	KI(esp_stat_in_requests);
    561   3448    dh155122 	KI(esp_stat_in_discards);
    562   3448    dh155122 	KI(esp_stat_lookup_failure);
    563   3448    dh155122 	KI(ah_stat_in_requests);
    564   3448    dh155122 	KI(ah_stat_in_discards);
    565   3448    dh155122 	KI(ah_stat_lookup_failure);
    566   3448    dh155122 	KI(sadb_acquire_maxpackets);
    567   3448    dh155122 	KI(sadb_acquire_qhiwater);
    568   3448    dh155122 #undef KI
    569   3448    dh155122 
    570   3448    dh155122 	kstat_install(ipss->ipsec_ksp);
    571   3448    dh155122 	return (B_TRUE);
    572   3448    dh155122 }
    573   3448    dh155122 
    574   3448    dh155122 static void
    575   3448    dh155122 ipsec_kstat_destroy(ipsec_stack_t *ipss)
    576   3448    dh155122 {
    577   3448    dh155122 	kstat_delete_netstack(ipss->ipsec_ksp,
    578   3448    dh155122 	    ipss->ipsec_netstack->netstack_stackid);
    579   3448    dh155122 	ipss->ipsec_kstats = NULL;
    580   3448    dh155122 
    581   3448    dh155122 }
    582   3448    dh155122 
    583   3448    dh155122 /*
    584   3448    dh155122  * Initialize the IPsec stack instance.
    585   3448    dh155122  */
    586   3448    dh155122 /* ARGSUSED */
    587   3448    dh155122 static void *
    588   3448    dh155122 ipsec_stack_init(netstackid_t stackid, netstack_t *ns)
    589   3448    dh155122 {
    590   3448    dh155122 	ipsec_stack_t	*ipss;
    591   3448    dh155122 	int i;
    592   3448    dh155122 
    593   3448    dh155122 	ipss = (ipsec_stack_t *)kmem_zalloc(sizeof (*ipss), KM_SLEEP);
    594   3448    dh155122 	ipss->ipsec_netstack = ns;
    595   3448    dh155122 
    596   3448    dh155122 	/*
    597   3448    dh155122 	 * FIXME: netstack_ipsec is used by some of the routines we call
    598   3448    dh155122 	 * below, but it isn't set until this routine returns.
    599   3448    dh155122 	 * Either we introduce optional xxx_stack_alloc() functions
    600   3448    dh155122 	 * that will be called by the netstack framework before xxx_stack_init,
    601   3448    dh155122 	 * or we switch spd.c and sadb.c to operate on ipsec_stack_t
    602   3448    dh155122 	 * (latter has some include file order issues for sadb.h, but makes
    603   3448    dh155122 	 * sense if we merge some of the ipsec related stack_t's together.
    604   3448    dh155122 	 */
    605   3448    dh155122 	ns->netstack_ipsec = ipss;
    606     81    sommerfe 
    607     81    sommerfe 	/*
    608     81    sommerfe 	 * Make two attempts to allocate policy hash tables; try it at
    609     81    sommerfe 	 * the "preferred" size (may be set in /etc/system) first,
    610     81    sommerfe 	 * then fall back to the default size.
    611     81    sommerfe 	 */
    612   5245      danmcd 	ipss->ipsec_spd_hashsize = (ipsec_spd_hashsize == 0) ?
    613   5245      danmcd 	    IPSEC_SPDHASH_DEFAULT : ipsec_spd_hashsize;
    614   3448    dh155122 
    615   3448    dh155122 	if (ipsec_alloc_tables(KM_NOSLEEP, ns) != 0) {
    616     81    sommerfe 		cmn_err(CE_WARN,
    617     81    sommerfe 		    "Unable to allocate %d entry IPsec policy hash table",
    618   3448    dh155122 		    ipss->ipsec_spd_hashsize);
    619   3448    dh155122 		ipss->ipsec_spd_hashsize = IPSEC_SPDHASH_DEFAULT;
    620     81    sommerfe 		cmn_err(CE_WARN, "Falling back to %d entries",
    621   3448    dh155122 		    ipss->ipsec_spd_hashsize);
    622   3448    dh155122 		(void) ipsec_alloc_tables(KM_SLEEP, ns);
    623     81    sommerfe 	}
    624     81    sommerfe 
    625   3055      danmcd 	/* Just set a default for tunnels. */
    626   5245      danmcd 	ipss->ipsec_tun_spd_hashsize = (tun_spd_hashsize == 0) ?
    627   5245      danmcd 	    TUN_SPDHASH_DEFAULT : tun_spd_hashsize;
    628   3448    dh155122 
    629   3448    dh155122 	ipsid_init(ns);
    630   3055      danmcd 	/*
    631   3055      danmcd 	 * Globals need ref == 1 to prevent IPPH_REFRELE() from attempting
    632   3055      danmcd 	 * to free them.
    633   3055      danmcd 	 */
    634   3448    dh155122 	ipss->ipsec_system_policy.iph_refs = 1;
    635   3448    dh155122 	ipss->ipsec_inactive_policy.iph_refs = 1;
    636   3448    dh155122 	ipsec_polhead_init(&ipss->ipsec_system_policy,
    637   3448    dh155122 	    ipss->ipsec_spd_hashsize);
    638   3448    dh155122 	ipsec_polhead_init(&ipss->ipsec_inactive_policy,
    639   3448    dh155122 	    ipss->ipsec_spd_hashsize);
    640   3448    dh155122 	rw_init(&ipss->ipsec_tunnel_policy_lock, NULL, RW_DEFAULT, NULL);
    641   3448    dh155122 	avl_create(&ipss->ipsec_tunnel_policies, tunnel_compare,
    642   3448    dh155122 	    sizeof (ipsec_tun_pol_t), 0);
    643   3448    dh155122 
    644   3448    dh155122 	ipss->ipsec_next_policy_index = 1;
    645   3448    dh155122 
    646   3448    dh155122 	rw_init(&ipss->ipsec_system_policy.iph_lock, NULL, RW_DEFAULT, NULL);
    647   3448    dh155122 	rw_init(&ipss->ipsec_inactive_policy.iph_lock, NULL, RW_DEFAULT, NULL);
    648      0      stevel 
    649      0      stevel 	for (i = 0; i < IPSEC_ACTION_HASH_SIZE; i++)
    650   3448    dh155122 		mutex_init(&(ipss->ipsec_action_hash[i].hash_lock),
    651      0      stevel 		    NULL, MUTEX_DEFAULT, NULL);
    652      0      stevel 
    653   3448    dh155122 	for (i = 0; i < ipss->ipsec_spd_hashsize; i++)
    654   3448    dh155122 		mutex_init(&(ipss->ipsec_sel_hash[i].hash_lock),
    655      0      stevel 		    NULL, MUTEX_DEFAULT, NULL);
    656      0      stevel 
    657   3448    dh155122 	mutex_init(&ipss->ipsec_alg_lock, NULL, MUTEX_DEFAULT, NULL);
    658   3448    dh155122 	for (i = 0; i < IPSEC_NALGTYPES; i++) {
    659   3448    dh155122 		ipss->ipsec_nalgs[i] = 0;
    660   3448    dh155122 	}
    661   3448    dh155122 
    662   3448    dh155122 	ip_drop_init(ipss);
    663   3448    dh155122 	ip_drop_register(&ipss->ipsec_spd_dropper, "IPsec SPD");
    664   3448    dh155122 
    665   3448    dh155122 	/* IP's IPsec code calls the packet dropper */
    666   3448    dh155122 	ip_drop_register(&ipss->ipsec_dropper, "IP IPsec processing");
    667   3448    dh155122 
    668   3448    dh155122 	(void) ipsec_kstat_init(ipss);
    669   3448    dh155122 
    670   3448    dh155122 	ipsec_loader_init(ipss);
    671   3448    dh155122 	ipsec_loader_start(ipss);
    672   3448    dh155122 
    673   3448    dh155122 	return (ipss);
    674   3448    dh155122 }
    675   3448    dh155122 
    676   3448    dh155122 /* Global across all stack instances */
    677   3448    dh155122 void
    678   3448    dh155122 ipsec_policy_g_init(void)
    679   3448    dh155122 {
    680      0      stevel 	ipsec_action_cache = kmem_cache_create("ipsec_actions",
    681      0      stevel 	    sizeof (ipsec_action_t), _POINTER_ALIGNMENT, NULL, NULL,
    682      0      stevel 	    ipsec_action_reclaim, NULL, NULL, 0);
    683      0      stevel 	ipsec_sel_cache = kmem_cache_create("ipsec_selectors",
    684      0      stevel 	    sizeof (ipsec_sel_t), _POINTER_ALIGNMENT, NULL, NULL,
    685      0      stevel 	    NULL, NULL, NULL, 0);
    686      0      stevel 	ipsec_pol_cache = kmem_cache_create("ipsec_policy",
    687      0      stevel 	    sizeof (ipsec_policy_t), _POINTER_ALIGNMENT, NULL, NULL,
    688      0      stevel 	    NULL, NULL, NULL, 0);
    689      0      stevel 
    690   3448    dh155122 	/*
    691   3448    dh155122 	 * We want to be informed each time a stack is created or
    692   3448    dh155122 	 * destroyed in the kernel, so we can maintain the
    693   3448    dh155122 	 * set of ipsec_stack_t's.
    694   3448    dh155122 	 */
    695   3448    dh155122 	netstack_register(NS_IPSEC, ipsec_stack_init, NULL, ipsec_stack_fini);
    696      0      stevel }
    697      0      stevel 
    698      0      stevel /*
    699      0      stevel  * Sort algorithm lists.
    700    134      danmcd  *
    701      0      stevel  * I may need to split this based on
    702      0      stevel  * authentication/encryption, and I may wish to have an administrator
    703      0      stevel  * configure this list.  Hold on to some NDD variables...
    704      0      stevel  *
    705      0      stevel  * XXX For now, sort on minimum key size (GAG!).  While minimum key size is
    706    134      danmcd  * not the ideal metric, it's the only quantifiable measure available.
    707    134      danmcd  * We need a better metric for sorting algorithms by preference.
    708      0      stevel  */
    709      0      stevel static void
    710   3448    dh155122 alg_insert_sortlist(enum ipsec_algtype at, uint8_t algid, netstack_t *ns)
    711   3448    dh155122 {
    712   3448    dh155122 	ipsec_stack_t	*ipss = ns->netstack_ipsec;
    713   3448    dh155122 	ipsec_alginfo_t *ai = ipss->ipsec_alglists[at][algid];
    714      0      stevel 	uint8_t holder, swap;
    715      0      stevel 	uint_t i;
    716   3448    dh155122 	uint_t count = ipss->ipsec_nalgs[at];
    717      0      stevel 	ASSERT(ai != NULL);
    718      0      stevel 	ASSERT(algid == ai->alg_id);
    719      0      stevel 
    720   3448    dh155122 	ASSERT(MUTEX_HELD(&ipss->ipsec_alg_lock));
    721      0      stevel 
    722      0      stevel 	holder = algid;
    723      0      stevel 
    724      0      stevel 	for (i = 0; i < count - 1; i++) {
    725      0      stevel 		ipsec_alginfo_t *alt;
    726      0      stevel 
    727   3448    dh155122 		alt = ipss->ipsec_alglists[at][ipss->ipsec_sortlist[at][i]];
    728      0      stevel 		/*
    729      0      stevel 		 * If you want to give precedence to newly added algs,
    730      0      stevel 		 * add the = in the > comparison.
    731      0      stevel 		 */
    732      0      stevel 		if ((holder != algid) || (ai->alg_minbits > alt->alg_minbits)) {
    733      0      stevel 			/* Swap sortlist[i] and holder. */
    734   3448    dh155122 			swap = ipss->ipsec_sortlist[at][i];
    735   3448    dh155122 			ipss->ipsec_sortlist[at][i] = holder;
    736      0      stevel 			holder = swap;
    737      0      stevel 			ai = alt;
    738      0      stevel 		} /* Else just continue. */
    739      0      stevel 	}
    740      0      stevel 
    741      0      stevel 	/* Store holder in last slot. */
    742   3448    dh155122 	ipss->ipsec_sortlist[at][i] = holder;
    743      0      stevel }
    744      0      stevel 
    745      0      stevel /*
    746      0      stevel  * Remove an algorithm from a sorted algorithm list.
    747      0      stevel  * This should be considerably easier, even with complex sorting.
    748      0      stevel  */
    749      0      stevel static void
    750   3448    dh155122 alg_remove_sortlist(enum ipsec_algtype at, uint8_t algid, netstack_t *ns)
    751      0      stevel {
    752      0      stevel 	boolean_t copyback = B_FALSE;
    753      0      stevel 	int i;
    754   3448    dh155122 	ipsec_stack_t	*ipss = ns->netstack_ipsec;
    755   3448    dh155122 	int newcount = ipss->ipsec_nalgs[at];
    756   3448    dh155122 
    757   3448    dh155122 	ASSERT(MUTEX_HELD(&ipss->ipsec_alg_lock));
    758      0      stevel 
    759      0      stevel 	for (i = 0; i <= newcount; i++) {
    760   3448    dh155122 		if (copyback) {
    761   3448    dh155122 			ipss->ipsec_sortlist[at][i-1] =
    762   3448    dh155122 			    ipss->ipsec_sortlist[at][i];
    763   3448    dh155122 		} else if (ipss->ipsec_sortlist[at][i] == algid) {
    764      0      stevel 			copyback = B_TRUE;
    765   3448    dh155122 		}
    766      0      stevel 	}
    767      0      stevel }
    768      0      stevel 
    769      0      stevel /*
    770      0      stevel  * Add the specified algorithm to the algorithm tables.
    771      0      stevel  * Must be called while holding the algorithm table writer lock.
    772      0      stevel  */
    773      0      stevel void
    774   3448    dh155122 ipsec_alg_reg(ipsec_algtype_t algtype, ipsec_alginfo_t *alg, netstack_t *ns)
    775   3448    dh155122 {
    776   3448    dh155122 	ipsec_stack_t	*ipss = ns->netstack_ipsec;
    777   3448    dh155122 
    778   3448    dh155122 	ASSERT(MUTEX_HELD(&ipss->ipsec_alg_lock));
    779   3448    dh155122 
    780   3448    dh155122 	ASSERT(ipss->ipsec_alglists[algtype][alg->alg_id] == NULL);
    781   3448    dh155122 	ipsec_alg_fix_min_max(alg, algtype, ns);
    782   3448    dh155122 	ipss->ipsec_alglists[algtype][alg->alg_id] = alg;
    783   3448    dh155122 
    784   3448    dh155122 	ipss->ipsec_nalgs[algtype]++;
    785   3448    dh155122 	alg_insert_sortlist(algtype, alg->alg_id, ns);
    786      0      stevel }
    787      0      stevel 
    788      0      stevel /*
    789      0      stevel  * Remove the specified algorithm from the algorithm tables.
    790      0      stevel  * Must be called while holding the algorithm table writer lock.
    791      0      stevel  */
    792      0      stevel void
    793   3448    dh155122 ipsec_alg_unreg(ipsec_algtype_t algtype, uint8_t algid, netstack_t *ns)
    794   3448    dh155122 {
    795   3448    dh155122 	ipsec_stack_t	*ipss = ns->netstack_ipsec;
    796   3448    dh155122 
    797   3448    dh155122 	ASSERT(MUTEX_HELD(&ipss->ipsec_alg_lock));
    798   3448    dh155122 
    799   3448    dh155122 	ASSERT(ipss->ipsec_alglists[algtype][algid] != NULL);
    800   3448    dh155122 	ipsec_alg_free(ipss->ipsec_alglists[algtype][algid]);
    801   3448    dh155122 	ipss->ipsec_alglists[algtype][algid] = NULL;
    802   3448    dh155122 
    803   3448    dh155122 	ipss->ipsec_nalgs[algtype]--;
    804   3448    dh155122 	alg_remove_sortlist(algtype, algid, ns);
    805      0      stevel }
    806      0      stevel 
    807      0      stevel /*
    808      0      stevel  * Hooks for spdsock to get a grip on system policy.
    809      0      stevel  */
    810      0      stevel 
    811      0      stevel ipsec_policy_head_t *
    812   3448    dh155122 ipsec_system_policy(netstack_t *ns)
    813   3448    dh155122 {
    814   3448    dh155122 	ipsec_stack_t	*ipss = ns->netstack_ipsec;
    815   3448    dh155122 	ipsec_policy_head_t *h = &ipss->ipsec_system_policy;
    816   3448    dh155122 
    817      0      stevel 	IPPH_REFHOLD(h);
    818      0      stevel 	return (h);
    819      0      stevel }
    820      0      stevel 
    821      0      stevel ipsec_policy_head_t *
    822   3448    dh155122 ipsec_inactive_policy(netstack_t *ns)
    823   3448    dh155122 {
    824   3448    dh155122 	ipsec_stack_t	*ipss = ns->netstack_ipsec;
    825   3448    dh155122 	ipsec_policy_head_t *h = &ipss->ipsec_inactive_policy;
    826   3448    dh155122 
    827      0      stevel 	IPPH_REFHOLD(h);
    828      0      stevel 	return (h);
    829      0      stevel }
    830      0      stevel 
    831      0      stevel /*
    832      0      stevel  * Lock inactive policy, then active policy, then exchange policy root
    833      0      stevel  * pointers.
    834      0      stevel  */
    835      0      stevel void
    836   3448    dh155122 ipsec_swap_policy(ipsec_policy_head_t *active, ipsec_policy_head_t *inactive,
    837   3448    dh155122     netstack_t *ns)
    838      0      stevel {
    839      0      stevel 	int af, dir;
    840     81    sommerfe 	avl_tree_t r1, r2;
    841      0      stevel 
    842   3055      danmcd 	rw_enter(&inactive->iph_lock, RW_WRITER);
    843   3055      danmcd 	rw_enter(&active->iph_lock, RW_WRITER);
    844   3055      danmcd 
    845   3055      danmcd 	r1 = active->iph_rulebyid;
    846   3055      danmcd 	r2 = inactive->iph_rulebyid;
    847   3055      danmcd 	active->iph_rulebyid = r2;
    848   3055      danmcd 	inactive->iph_rulebyid = r1;
    849     81    sommerfe 
    850     81    sommerfe 	for (dir = 0; dir < IPSEC_NTYPES; dir++) {
    851     81    sommerfe 		ipsec_policy_hash_t *h1, *h2;
    852     81    sommerfe 
    853   3055      danmcd 		h1 = active->iph_root[dir].ipr_hash;
    854   3055      danmcd 		h2 = inactive->iph_root[dir].ipr_hash;
    855   3055      danmcd 		active->iph_root[dir].ipr_hash = h2;
    856   3055      danmcd 		inactive->iph_root[dir].ipr_hash = h1;
    857     81    sommerfe 
    858      0      stevel 		for (af = 0; af < IPSEC_NAF; af++) {
    859     81    sommerfe 			ipsec_policy_t *t1, *t2;
    860     81    sommerfe 
    861   3055      danmcd 			t1 = active->iph_root[dir].ipr_nonhash[af];
    862   3055      danmcd 			t2 = inactive->iph_root[dir].ipr_nonhash[af];
    863   3055      danmcd 			active->iph_root[dir].ipr_nonhash[af] = t2;
    864   3055      danmcd 			inactive->iph_root[dir].ipr_nonhash[af] = t1;
    865     81    sommerfe 			if (t1 != NULL) {
    866     81    sommerfe 				t1->ipsp_hash.hash_pp =
    867   3055      danmcd 				    &(inactive->iph_root[dir].ipr_nonhash[af]);
    868     81    sommerfe 			}
    869     81    sommerfe 			if (t2 != NULL) {
    870     81    sommerfe 				t2->ipsp_hash.hash_pp =
    871   3055      danmcd 				    &(active->iph_root[dir].ipr_nonhash[af]);
    872   3055      danmcd 			}
    873   3055      danmcd 
    874   3055      danmcd 		}
    875   3055      danmcd 	}
    876   3055      danmcd 	active->iph_gen++;
    877   3055      danmcd 	inactive->iph_gen++;
    878   3448    dh155122 	ipsec_update_present_flags(ns->netstack_ipsec);
    879   3055      danmcd 	rw_exit(&active->iph_lock);
    880   3055      danmcd 	rw_exit(&inactive->iph_lock);
    881   3055      danmcd }
    882   3055      danmcd 
    883   3055      danmcd /*
    884   3055      danmcd  * Swap global policy primary/secondary.
    885   3055      danmcd  */
    886   3055      danmcd void
    887   3448    dh155122 ipsec_swap_global_policy(netstack_t *ns)
    888   3448    dh155122 {
    889   3448    dh155122 	ipsec_stack_t	*ipss = ns->netstack_ipsec;
    890   3448    dh155122 
    891   3448    dh155122 	ipsec_swap_policy(&ipss->ipsec_system_policy,
    892   3448    dh155122 	    &ipss->ipsec_inactive_policy, ns);
    893      0      stevel }
    894      0      stevel 
    895      0      stevel /*
    896      0      stevel  * Clone one policy rule..
    897      0      stevel  */
    898      0      stevel static ipsec_policy_t *
    899      0      stevel ipsec_copy_policy(const ipsec_policy_t *src)
    900      0      stevel {
    901      0      stevel 	ipsec_policy_t *dst = kmem_cache_alloc(ipsec_pol_cache, KM_NOSLEEP);
    902      0      stevel 
    903      0      stevel 	if (dst == NULL)
    904      0      stevel 		return (NULL);
    905      0      stevel 
    906      0      stevel 	/*
    907      0      stevel 	 * Adjust refcounts of cloned state.
    908      0      stevel 	 */
    909      0      stevel 	IPACT_REFHOLD(src->ipsp_act);
    910      0      stevel 	src->ipsp_sel->ipsl_refs++;
    911      0      stevel 
    912     81    sommerfe 	HASH_NULL(dst, ipsp_hash);
    913  11042        Erik 	dst->ipsp_netstack = src->ipsp_netstack;
    914      0      stevel 	dst->ipsp_refs = 1;
    915      0      stevel 	dst->ipsp_sel = src->ipsp_sel;
    916      0      stevel 	dst->ipsp_act = src->ipsp_act;
    917      0      stevel 	dst->ipsp_prio = src->ipsp_prio;
    918      0      stevel 	dst->ipsp_index = src->ipsp_index;
    919      0      stevel 
    920      0      stevel 	return (dst);
    921      0      stevel }
    922      0      stevel 
    923     81    sommerfe void
    924     81    sommerfe ipsec_insert_always(avl_tree_t *tree, void *new_node)
    925     81    sommerfe {
    926     81    sommerfe 	void *node;
    927     81    sommerfe 	avl_index_t where;
    928     81    sommerfe 
    929     81    sommerfe 	node = avl_find(tree, new_node, &where);
    930     81    sommerfe 	ASSERT(node == NULL);
    931     81    sommerfe 	avl_insert(tree, new_node, where);
    932     81    sommerfe }
    933     81    sommerfe 
    934     81    sommerfe 
    935     81    sommerfe static int
    936     81    sommerfe ipsec_copy_chain(ipsec_policy_head_t *dph, ipsec_policy_t *src,
    937     81    sommerfe     ipsec_policy_t **dstp)
    938     81    sommerfe {
    939     81    sommerfe 	for (; src != NULL; src = src->ipsp_hash.hash_next) {
    940     81    sommerfe 		ipsec_policy_t *dst = ipsec_copy_policy(src);
    941     81    sommerfe 		if (dst == NULL)
    942     81    sommerfe 			return (ENOMEM);
    943     81    sommerfe 
    944     81    sommerfe 		HASHLIST_INSERT(dst, ipsp_hash, *dstp);
    945     81    sommerfe 		ipsec_insert_always(&dph->iph_rulebyid, dst);
    946     81    sommerfe 	}
    947     81    sommerfe 	return (0);
    948     81    sommerfe }
    949     81    sommerfe 
    950     81    sommerfe 
    951     81    sommerfe 
    952      0      stevel /*
    953      0      stevel  * Make one policy head look exactly like another.
    954      0      stevel  *
    955      0      stevel  * As with ipsec_swap_policy, we lock the destination policy head first, then
    956      0      stevel  * the source policy head. Note that we only need to read-lock the source
    957      0      stevel  * policy head as we are not changing it.
    958      0      stevel  */
    959   3055      danmcd int
    960   3448    dh155122 ipsec_copy_polhead(ipsec_policy_head_t *sph, ipsec_policy_head_t *dph,
    961   3448    dh155122     netstack_t *ns)
    962      0      stevel {
    963     81    sommerfe 	int af, dir, chain, nchains;
    964      0      stevel 
    965      0      stevel 	rw_enter(&dph->iph_lock, RW_WRITER);
    966      0      stevel 
    967   3448    dh155122 	ipsec_polhead_flush(dph, ns);
    968      0      stevel 
    969      0      stevel 	rw_enter(&sph->iph_lock, RW_READER);
    970      0      stevel 
    971      0      stevel 	for (dir = 0; dir < IPSEC_NTYPES; dir++) {
    972     81    sommerfe 		ipsec_policy_root_t *dpr = &dph->iph_root[dir];
    973     81    sommerfe 		ipsec_policy_root_t *spr = &sph->iph_root[dir];
    974     81    sommerfe 		nchains = dpr->ipr_nchains;
    975     81    sommerfe 
    976     81    sommerfe 		ASSERT(dpr->ipr_nchains == spr->ipr_nchains);
    977     81    sommerfe 
    978      0      stevel 		for (af = 0; af < IPSEC_NAF; af++) {
    979     81    sommerfe 			if (ipsec_copy_chain(dph, spr->ipr_nonhash[af],
    980     81    sommerfe 			    &dpr->ipr_nonhash[af]))
    981     81    sommerfe 				goto abort_copy;
    982     81    sommerfe 		}
    983     81    sommerfe 
    984     81    sommerfe 		for (chain = 0; chain < nchains; chain++) {
    985     81    sommerfe 			if (ipsec_copy_chain(dph,
    986     81    sommerfe 			    spr->ipr_hash[chain].hash_head,
    987     81    sommerfe 			    &dpr->ipr_hash[chain].hash_head))
    988     81    sommerfe 				goto abort_copy;
    989      0      stevel 		}
    990      0      stevel 	}
    991      0      stevel 
    992      0      stevel 	dph->iph_gen++;
    993      0      stevel 
    994      0      stevel 	rw_exit(&sph->iph_lock);
    995      0      stevel 	rw_exit(&dph->iph_lock);
    996      0      stevel 	return (0);
    997     81    sommerfe 
    998     81    sommerfe abort_copy:
    999   3448    dh155122 	ipsec_polhead_flush(dph, ns);
   1000     81    sommerfe 	rw_exit(&sph->iph_lock);
   1001     81    sommerfe 	rw_exit(&dph->iph_lock);
   1002     81    sommerfe 	return (ENOMEM);
   1003      0      stevel }
   1004      0      stevel 
   1005      0      stevel /*
   1006      0      stevel  * Clone currently active policy to the inactive policy list.
   1007      0      stevel  */
   1008      0      stevel int
   1009   3448    dh155122 ipsec_clone_system_policy(netstack_t *ns)
   1010   3448    dh155122 {
   1011   3448    dh155122 	ipsec_stack_t	*ipss = ns->netstack_ipsec;
   1012   3448    dh155122 
   1013   3448    dh155122 	return (ipsec_copy_polhead(&ipss->ipsec_system_policy,
   1014   5245      danmcd 	    &ipss->ipsec_inactive_policy, ns));
   1015      0      stevel }
   1016      0      stevel 
   1017   3055      danmcd /*
   1018      0      stevel  * Extract the string from ipsec_policy_failure_msgs[type] and
   1019      0      stevel  * log it.
   1020      0      stevel  *
   1021      0      stevel  */
   1022      0      stevel void
   1023   3192      danmcd ipsec_log_policy_failure(int type, char *func_name, ipha_t *ipha, ip6_t *ip6h,
   1024   3448    dh155122     boolean_t secure, netstack_t *ns)
   1025      0      stevel {
   1026      0      stevel 	char	sbuf[INET6_ADDRSTRLEN];
   1027      0      stevel 	char	dbuf[INET6_ADDRSTRLEN];
   1028      0      stevel 	char	*s;
   1029      0      stevel 	char	*d;
   1030   3448    dh155122 	ipsec_stack_t	*ipss = ns->netstack_ipsec;
   1031      0      stevel 
   1032      0      stevel 	ASSERT((ipha == NULL && ip6h != NULL) ||
   1033      0      stevel 	    (ip6h == NULL && ipha != NULL));
   1034      0      stevel 
   1035      0      stevel 	if (ipha != NULL) {
   1036      0      stevel 		s = inet_ntop(AF_INET, &ipha->ipha_src, sbuf, sizeof (sbuf));
   1037      0      stevel 		d = inet_ntop(AF_INET, &ipha->ipha_dst, dbuf, sizeof (dbuf));
   1038      0      stevel 	} else {
   1039      0      stevel 		s = inet_ntop(AF_INET6, &ip6h->ip6_src, sbuf, sizeof (sbuf));
   1040      0      stevel 		d = inet_ntop(AF_INET6, &ip6h->ip6_dst, dbuf, sizeof (dbuf));
   1041      0      stevel 
   1042      0      stevel 	}
   1043      0      stevel 
   1044      0      stevel 	/* Always bump the policy failure counter. */
   1045   3448    dh155122 	ipss->ipsec_policy_failure_count[type]++;
   1046   3448    dh155122 
   1047   3448    dh155122 	ipsec_rl_strlog(ns, IP_MOD_ID, 0, 0, SL_ERROR|SL_WARN|SL_CONSOLE,
   1048   3192      danmcd 	    ipsec_policy_failure_msgs[type], func_name,
   1049   3192      danmcd 	    (secure ? "secure" : "not secure"), s, d);
   1050   1659     markfen }
   1051   1659     markfen 
   1052   1659     markfen /*
   1053   1659     markfen  * Rate-limiting front-end to strlog() for AH and ESP.	Uses the ndd variables
   1054   1659     markfen  * in /dev/ip and the same rate-limiting clock so that there's a single
   1055   1659     markfen  * knob to turn to throttle the rate of messages.
   1056   1659     markfen  */
   1057   1659     markfen void
   1058   3448    dh155122 ipsec_rl_strlog(netstack_t *ns, short mid, short sid, char level, ushort_t sl,
   1059   3448    dh155122     char *fmt, ...)
   1060   1659     markfen {
   1061   1659     markfen 	va_list adx;
   1062   1659     markfen 	hrtime_t current = gethrtime();
   1063   3448    dh155122 	ip_stack_t	*ipst = ns->netstack_ip;
   1064   3448    dh155122 	ipsec_stack_t	*ipss = ns->netstack_ipsec;
   1065   1659     markfen 
   1066   1659     markfen 	sl |= SL_CONSOLE;
   1067   1659     markfen 	/*
   1068   1659     markfen 	 * Throttle logging to stop syslog from being swamped. If variable
   1069   1659     markfen 	 * 'ipsec_policy_log_interval' is zero, don't log any messages at
   1070   1659     markfen 	 * all, otherwise log only one message every 'ipsec_policy_log_interval'
   1071   1659     markfen 	 * msec. Convert interval (in msec) to hrtime (in nsec).
   1072   1659     markfen 	 */
   1073   1659     markfen 
   1074   3448    dh155122 	if (ipst->ips_ipsec_policy_log_interval) {
   1075   3448    dh155122 		if (ipss->ipsec_policy_failure_last +
   1076   3448    dh155122 		    ((hrtime_t)ipst->ips_ipsec_policy_log_interval *
   1077   3448    dh155122 		    (hrtime_t)1000000) <= current) {
   1078   1659     markfen 			va_start(adx, fmt);
   1079   1659     markfen 			(void) vstrlog(mid, sid, level, sl, fmt, adx);
   1080   1659     markfen 			va_end(adx);
   1081   3448    dh155122 			ipss->ipsec_policy_failure_last = current;
   1082   3448    dh155122 		}
   1083   3448    dh155122 	}
   1084   3448    dh155122 }
   1085   3448    dh155122 
   1086   3448    dh155122 void
   1087   3448    dh155122 ipsec_config_flush(netstack_t *ns)
   1088   3448    dh155122 {
   1089   3448    dh155122 	ipsec_stack_t	*ipss = ns->netstack_ipsec;
   1090   3448    dh155122 
   1091   3448    dh155122 	rw_enter(&ipss->ipsec_system_policy.iph_lock, RW_WRITER);
   1092   3448    dh155122 	ipsec_polhead_flush(&ipss->ipsec_system_policy, ns);
   1093   3448    dh155122 	ipss->ipsec_next_policy_index = 1;
   1094   3448    dh155122 	rw_exit(&ipss->ipsec_system_policy.iph_lock);
   1095   3448    dh155122 	ipsec_action_reclaim_stack(ns);
   1096      0      stevel }
   1097      0      stevel 
   1098      0      stevel /*
   1099      0      stevel  * Clip a policy's min/max keybits vs. the capabilities of the
   1100      0      stevel  * algorithm.
   1101      0      stevel  */
   1102      0      stevel static void
   1103      0      stevel act_alg_adjust(uint_t algtype, uint_t algid,
   1104   3448    dh155122     uint16_t *minbits, uint16_t *maxbits, netstack_t *ns)
   1105   3448    dh155122 {
   1106   3448    dh155122 	ipsec_stack_t	*ipss = ns->netstack_ipsec;
   1107   3448    dh155122 	ipsec_alginfo_t *algp = ipss->ipsec_alglists[algtype][algid];
   1108   3448    dh155122 
   1109      0      stevel 	if (algp != NULL) {
   1110      0      stevel 		/*
   1111      0      stevel 		 * If passed-in minbits is zero, we assume the caller trusts
   1112      0      stevel 		 * us with setting the minimum key size.  We pick the
   1113      0      stevel 		 * algorithms DEFAULT key size for the minimum in this case.
   1114      0      stevel 		 */
   1115      0      stevel 		if (*minbits == 0) {
   1116      0      stevel 			*minbits = algp->alg_default_bits;
   1117      0      stevel 			ASSERT(*minbits >= algp->alg_minbits);
   1118      0      stevel 		} else {
   1119   3055      danmcd 			*minbits = MAX(MIN(*minbits, algp->alg_maxbits),
   1120   3055      danmcd 			    algp->alg_minbits);
   1121      0      stevel 		}
   1122      0      stevel 		if (*maxbits == 0)
   1123      0      stevel 			*maxbits = algp->alg_maxbits;
   1124      0      stevel 		else
   1125   3055      danmcd 			*maxbits = MIN(MAX(*maxbits, algp->alg_minbits),
   1126   3055      danmcd 			    algp->alg_maxbits);
   1127      0      stevel 		ASSERT(*minbits <= *maxbits);
   1128      0      stevel 	} else {
   1129      0      stevel 		*minbits = 0;
   1130      0      stevel 		*maxbits = 0;
   1131      0      stevel 	}
   1132      0      stevel }
   1133      0      stevel 
   1134      0      stevel /*
   1135      0      stevel  * Check an action's requested algorithms against the algorithms currently
   1136      0      stevel  * loaded in the system.
   1137      0      stevel  */
   1138      0      stevel boolean_t
   1139   3448    dh155122 ipsec_check_action(ipsec_act_t *act, int *diag, netstack_t *ns)
   1140      0      stevel {
   1141      0      stevel 	ipsec_prot_t *ipp;
   1142   3448    dh155122 	ipsec_stack_t	*ipss = ns->netstack_ipsec;
   1143      0      stevel 
   1144      0      stevel 	ipp = &act->ipa_apply;
   1145      0      stevel 
   1146      0      stevel 	if (ipp->ipp_use_ah &&
   1147   3448    dh155122 	    ipss->ipsec_alglists[IPSEC_ALG_AUTH][ipp->ipp_auth_alg] == NULL) {
   1148      0      stevel 		*diag = SPD_DIAGNOSTIC_UNSUPP_AH_ALG;
   1149      0      stevel 		return (B_FALSE);
   1150      0      stevel 	}
   1151      0      stevel 	if (ipp->ipp_use_espa &&
   1152   3448    dh155122 	    ipss->ipsec_alglists[IPSEC_ALG_AUTH][ipp->ipp_esp_auth_alg] ==
   1153   3448    dh155122 	    NULL) {
   1154      0      stevel 		*diag = SPD_DIAGNOSTIC_UNSUPP_ESP_AUTH_ALG;
   1155      0      stevel 		return (B_FALSE);
   1156      0      stevel 	}
   1157      0      stevel 	if (ipp->ipp_use_esp &&
   1158   3448    dh155122 	    ipss->ipsec_alglists[IPSEC_ALG_ENCR][ipp->ipp_encr_alg] == NULL) {
   1159      0      stevel 		*diag = SPD_DIAGNOSTIC_UNSUPP_ESP_ENCR_ALG;
   1160      0      stevel 		return (B_FALSE);
   1161      0      stevel 	}
   1162      0      stevel 
   1163      0      stevel 	act_alg_adjust(IPSEC_ALG_AUTH, ipp->ipp_auth_alg,
   1164   3448    dh155122 	    &ipp->ipp_ah_minbits, &ipp->ipp_ah_maxbits, ns);
   1165      0      stevel 	act_alg_adjust(IPSEC_ALG_AUTH, ipp->ipp_esp_auth_alg,
   1166   3448    dh155122 	    &ipp->ipp_espa_minbits, &ipp->ipp_espa_maxbits, ns);
   1167      0      stevel 	act_alg_adjust(IPSEC_ALG_ENCR, ipp->ipp_encr_alg,
   1168   3448    dh155122 	    &ipp->ipp_espe_minbits, &ipp->ipp_espe_maxbits, ns);
   1169      0      stevel 
   1170      0      stevel 	if (ipp->ipp_ah_minbits > ipp->ipp_ah_maxbits) {
   1171      0      stevel 		*diag = SPD_DIAGNOSTIC_UNSUPP_AH_KEYSIZE;
   1172      0      stevel 		return (B_FALSE);
   1173      0      stevel 	}
   1174      0      stevel 	if (ipp->ipp_espa_minbits > ipp->ipp_espa_maxbits) {
   1175      0      stevel 		*diag = SPD_DIAGNOSTIC_UNSUPP_ESP_AUTH_KEYSIZE;
   1176      0      stevel 		return (B_FALSE);
   1177      0      stevel 	}
   1178      0      stevel 	if (ipp->ipp_espe_minbits > ipp->ipp_espe_maxbits) {
   1179      0      stevel 		*diag = SPD_DIAGNOSTIC_UNSUPP_ESP_ENCR_KEYSIZE;
   1180      0      stevel 		return (B_FALSE);
   1181      0      stevel 	}
   1182      0      stevel 	/* TODO: sanity check lifetimes */
   1183      0      stevel 	return (B_TRUE);
   1184      0      stevel }
   1185      0      stevel 
   1186      0      stevel /*
   1187      0      stevel  * Set up a single action during wildcard expansion..
   1188      0      stevel  */
   1189      0      stevel static void
   1190      0      stevel ipsec_setup_act(ipsec_act_t *outact, ipsec_act_t *act,
   1191   3448    dh155122     uint_t auth_alg, uint_t encr_alg, uint_t eauth_alg, netstack_t *ns)
   1192      0      stevel {
   1193      0      stevel 	ipsec_prot_t *ipp;
   1194      0      stevel 
   1195      0      stevel 	*outact = *act;
   1196      0      stevel 	ipp = &outact->ipa_apply;
   1197      0      stevel 	ipp->ipp_auth_alg = (uint8_t)auth_alg;
   1198      0      stevel 	ipp->ipp_encr_alg = (uint8_t)encr_alg;
   1199      0      stevel 	ipp->ipp_esp_auth_alg = (uint8_t)eauth_alg;
   1200      0      stevel 
   1201      0      stevel 	act_alg_adjust(IPSEC_ALG_AUTH, auth_alg,
   1202   3448    dh155122 	    &ipp->ipp_ah_minbits, &ipp->ipp_ah_maxbits, ns);
   1203      0      stevel 	act_alg_adjust(IPSEC_ALG_AUTH, eauth_alg,
   1204   3448    dh155122 	    &ipp->ipp_espa_minbits, &ipp->ipp_espa_maxbits, ns);
   1205      0      stevel 	act_alg_adjust(IPSEC_ALG_ENCR, encr_alg,
   1206   3448    dh155122 	    &ipp->ipp_espe_minbits, &ipp->ipp_espe_maxbits, ns);
   1207      0      stevel }
   1208      0      stevel 
   1209      0      stevel /*
   1210      0      stevel  * combinatoric expansion time: expand a wildcarded action into an
   1211      0      stevel  * array of wildcarded actions; we return the exploded action list,
   1212      0      stevel  * and return a count in *nact (output only).
   1213      0      stevel  */
   1214      0      stevel static ipsec_act_t *
   1215   3448    dh155122 ipsec_act_wildcard_expand(ipsec_act_t *act, uint_t *nact, netstack_t *ns)
   1216      0      stevel {
   1217      0      stevel 	boolean_t use_ah, use_esp, use_espa;
   1218      0      stevel 	boolean_t wild_auth, wild_encr, wild_eauth;
   1219      0      stevel 	uint_t	auth_alg, auth_idx, auth_min, auth_max;
   1220      0      stevel 	uint_t	eauth_alg, eauth_idx, eauth_min, eauth_max;
   1221      0      stevel 	uint_t  encr_alg, encr_idx, encr_min, encr_max;
   1222      0      stevel 	uint_t	action_count, ai;
   1223      0      stevel 	ipsec_act_t *outact;
   1224   3448    dh155122 	ipsec_stack_t	*ipss = ns->netstack_ipsec;
   1225      0      stevel 
   1226      0      stevel 	if (act->ipa_type != IPSEC_ACT_APPLY) {
   1227      0      stevel 		outact = kmem_alloc(sizeof (*act), KM_NOSLEEP);
   1228      0      stevel 		*nact = 1;
   1229      0      stevel 		if (outact != NULL)
   1230      0      stevel 			bcopy(act, outact, sizeof (*act));
   1231      0      stevel 		return (outact);
   1232      0      stevel 	}
   1233      0      stevel 	/*
   1234      0      stevel 	 * compute the combinatoric explosion..
   1235      0      stevel 	 *
   1236      0      stevel 	 * we assume a request for encr if esp_req is PREF_REQUIRED
   1237      0      stevel 	 * we assume a request for ah auth if ah_req is PREF_REQUIRED.
   1238      0      stevel 	 * we assume a request for esp auth if !ah and esp_req is PREF_REQUIRED
   1239      0      stevel 	 */
   1240      0      stevel 
   1241      0      stevel 	use_ah = act->ipa_apply.ipp_use_ah;
   1242      0      stevel 	use_esp = act->ipa_apply.ipp_use_esp;
   1243      0      stevel 	use_espa = act->ipa_apply.ipp_use_espa;
   1244      0      stevel 	auth_alg = act->ipa_apply.ipp_auth_alg;
   1245      0      stevel 	eauth_alg = act->ipa_apply.ipp_esp_auth_alg;
   1246      0      stevel 	encr_alg = act->ipa_apply.ipp_encr_alg;
   1247      0      stevel 
   1248      0      stevel 	wild_auth = use_ah && (auth_alg == 0);
   1249      0      stevel 	wild_eauth = use_espa && (eauth_alg == 0);
   1250      0      stevel 	wild_encr = use_esp && (encr_alg == 0);
   1251      0      stevel 
   1252      0      stevel 	action_count = 1;
   1253      0      stevel 	auth_min = auth_max = auth_alg;
   1254      0      stevel 	eauth_min = eauth_max = eauth_alg;
   1255      0      stevel 	encr_min = encr_max = encr_alg;
   1256      0      stevel 
   1257      0      stevel 	/*
   1258      0      stevel 	 * set up for explosion.. for each dimension, expand output
   1259      0      stevel 	 * size by the explosion factor.
   1260      0      stevel 	 *
   1261      0      stevel 	 * Don't include the "any" algorithms, if defined, as no
   1262      0      stevel 	 * kernel policies should be set for these algorithms.
   1263      0      stevel 	 */
   1264      0      stevel 
   1265   3448    dh155122 #define	SET_EXP_MINMAX(type, wild, alg, min, max, ipss)		\
   1266   3448    dh155122 	if (wild) {						\
   1267   3448    dh155122 		int nalgs = ipss->ipsec_nalgs[type];		\
   1268   3448    dh155122 		if (ipss->ipsec_alglists[type][alg] != NULL)	\
   1269      0      stevel 			nalgs--;				\
   1270      0      stevel 		action_count *= nalgs;				\
   1271      0      stevel 		min = 0;					\
   1272   3448    dh155122 		max = ipss->ipsec_nalgs[type] - 1;		\
   1273      0      stevel 	}
   1274      0      stevel 
   1275      0      stevel 	SET_EXP_MINMAX(IPSEC_ALG_AUTH, wild_auth, SADB_AALG_NONE,
   1276   3448    dh155122 	    auth_min, auth_max, ipss);
   1277      0      stevel 	SET_EXP_MINMAX(IPSEC_ALG_AUTH, wild_eauth, SADB_AALG_NONE,
   1278   3448    dh155122 	    eauth_min, eauth_max, ipss);
   1279      0      stevel 	SET_EXP_MINMAX(IPSEC_ALG_ENCR, wild_encr, SADB_EALG_NONE,
   1280   3448    dh155122 	    encr_min, encr_max, ipss);
   1281      0      stevel 
   1282      0      stevel #undef	SET_EXP_MINMAX
   1283      0      stevel 
   1284      0      stevel 	/*
   1285      0      stevel 	 * ok, allocate the whole mess..
   1286      0      stevel 	 */
   1287      0      stevel 
   1288      0      stevel 	outact = kmem_alloc(sizeof (*outact) * action_count, KM_NOSLEEP);
   1289      0      stevel 	if (outact == NULL)
   1290      0      stevel 		return (NULL);
   1291      0      stevel 
   1292      0      stevel 	/*
   1293      0      stevel 	 * Now compute all combinations.  Note that non-wildcarded
   1294      0      stevel 	 * dimensions just get a single value from auth_min, while
   1295      0      stevel 	 * wildcarded dimensions indirect through the sortlist.
   1296      0      stevel 	 *
   1297      0      stevel 	 * We do encryption outermost since, at this time, there's
   1298      0      stevel 	 * greater difference in security and performance between
   1299      0      stevel 	 * encryption algorithms vs. authentication algorithms.
   1300      0      stevel 	 */
   1301      0      stevel 
   1302      0      stevel 	ai = 0;
   1303      0      stevel 
   1304   3448    dh155122 #define	WHICH_ALG(type, wild, idx, ipss) \
   1305   3448    dh155122 	((wild)?(ipss->ipsec_sortlist[type][idx]):(idx))
   1306      0      stevel 
   1307      0      stevel 	for (encr_idx = encr_min; encr_idx <= encr_max; encr_idx++) {
   1308   3448    dh155122 		encr_alg = WHICH_ALG(IPSEC_ALG_ENCR, wild_encr, encr_idx, ipss);
   1309      0      stevel 		if (wild_encr && encr_alg == SADB_EALG_NONE)
   1310      0      stevel 			continue;
   1311      0      stevel 		for (auth_idx = auth_min; auth_idx <= auth_max; auth_idx++) {
   1312      0      stevel 			auth_alg = WHICH_ALG(IPSEC_ALG_AUTH, wild_auth,
   1313   3448    dh155122 			    auth_idx, ipss);
   1314      0      stevel 			if (wild_auth && auth_alg == SADB_AALG_NONE)
   1315      0      stevel 				continue;
   1316      0      stevel 			for (eauth_idx = eauth_min; eauth_idx <= eauth_max;
   1317      0      stevel 			    eauth_idx++) {
   1318      0      stevel 				eauth_alg = WHICH_ALG(IPSEC_ALG_AUTH,
   1319   3448    dh155122 				    wild_eauth, eauth_idx, ipss);
   1320      0      stevel 				if (wild_eauth && eauth_alg == SADB_AALG_NONE)
   1321      0      stevel 					continue;
   1322      0      stevel 
   1323      0      stevel 				ipsec_setup_act(&outact[ai], act,
   1324   3448    dh155122 				    auth_alg, encr_alg, eauth_alg, ns);
   1325      0      stevel 				ai++;
   1326      0      stevel 			}
   1327      0      stevel 		}
   1328      0      stevel 	}
   1329      0      stevel 
   1330      0      stevel #undef WHICH_ALG
   1331      0      stevel 
   1332      0      stevel 	ASSERT(ai == action_count);
   1333      0      stevel 	*nact = action_count;
   1334      0      stevel 	return (outact);
   1335      0      stevel }
   1336      0      stevel 
   1337      0      stevel /*
   1338      0      stevel  * Extract the parts of an ipsec_prot_t from an old-style ipsec_req_t.
   1339      0      stevel  */
   1340      0      stevel static void
   1341  10616   Sebastien ipsec_prot_from_req(const ipsec_req_t *req, ipsec_prot_t *ipp)
   1342      0      stevel {
   1343      0      stevel 	bzero(ipp, sizeof (*ipp));
   1344      0      stevel 	/*
   1345      0      stevel 	 * ipp_use_* are bitfields.  Look at "!!" in the following as a
   1346      0      stevel 	 * "boolean canonicalization" operator.
   1347      0      stevel 	 */
   1348      0      stevel 	ipp->ipp_use_ah = !!(req->ipsr_ah_req & IPSEC_PREF_REQUIRED);
   1349      0      stevel 	ipp->ipp_use_esp = !!(req->ipsr_esp_req & IPSEC_PREF_REQUIRED);
   1350   6524     pwernau 	ipp->ipp_use_espa = !!(req->ipsr_esp_auth_alg);
   1351      0      stevel 	ipp->ipp_use_se = !!(req->ipsr_self_encap_req & IPSEC_PREF_REQUIRED);
   1352      0      stevel 	ipp->ipp_use_unique = !!((req->ipsr_ah_req|req->ipsr_esp_req) &
   1353      0      stevel 	    IPSEC_PREF_UNIQUE);
   1354      0      stevel 	ipp->ipp_encr_alg = req->ipsr_esp_alg;
   1355   6524     pwernau 	/*
   1356   6524     pwernau 	 * SADB_AALG_ANY is a placeholder to distinguish "any" from
   1357   6524     pwernau 	 * "none" above.  If auth is required, as determined above,
   1358   6524     pwernau 	 * SADB_AALG_ANY becomes 0, which is the representation
   1359   6524     pwernau 	 * of "any" and "none" in PF_KEY v2.
   1360   6524     pwernau 	 */
   1361   6524     pwernau 	ipp->ipp_auth_alg = (req->ipsr_auth_alg != SADB_AALG_ANY) ?
   1362   6524     pwernau 	    req->ipsr_auth_alg : 0;
   1363   6524     pwernau 	ipp->ipp_esp_auth_alg = (req->ipsr_esp_auth_alg != SADB_AALG_ANY) ?
   1364   6524     pwernau 	    req->ipsr_esp_auth_alg : 0;
   1365      0      stevel }
   1366      0      stevel 
   1367      0      stevel /*
   1368      0      stevel  * Extract a new-style action from a request.
   1369      0      stevel  */
   1370      0      stevel void
   1371  10616   Sebastien ipsec_actvec_from_req(const ipsec_req_t *req, ipsec_act_t **actp, uint_t *nactp,
   1372   3448    dh155122     netstack_t *ns)
   1373      0      stevel {
   1374      0      stevel 	struct ipsec_act act;
   1375   3448    dh155122 
   1376      0      stevel 	bzero(&act, sizeof (act));
   1377      0      stevel 	if ((req->ipsr_ah_req & IPSEC_PREF_NEVER) &&
   1378      0      stevel 	    (req->ipsr_esp_req & IPSEC_PREF_NEVER)) {
   1379      0      stevel 		act.ipa_type = IPSEC_ACT_BYPASS;
   1380      0      stevel 	} else {
   1381      0      stevel 		act.ipa_type = IPSEC_ACT_APPLY;
   1382      0      stevel 		ipsec_prot_from_req(req, &act.ipa_apply);
   1383      0      stevel 	}
   1384   3448    dh155122 	*actp = ipsec_act_wildcard_expand(&act, nactp, ns);
   1385      0      stevel }
   1386      0      stevel 
   1387      0      stevel /*
   1388      0      stevel  * Convert a new-style "prot" back to an ipsec_req_t (more backwards compat).
   1389      0      stevel  * We assume caller has already zero'ed *req for us.
   1390      0      stevel  */
   1391      0      stevel static int
   1392      0      stevel ipsec_req_from_prot(ipsec_prot_t *ipp, ipsec_req_t *req)
   1393      0      stevel {
   1394      0      stevel 	req->ipsr_esp_alg = ipp->ipp_encr_alg;
   1395      0      stevel 	req->ipsr_auth_alg = ipp->ipp_auth_alg;
   1396      0      stevel 	req->ipsr_esp_auth_alg = ipp->ipp_esp_auth_alg;
   1397      0      stevel 
   1398      0      stevel 	if (ipp->ipp_use_unique) {
   1399      0      stevel 		req->ipsr_ah_req |= IPSEC_PREF_UNIQUE;
   1400      0      stevel 		req->ipsr_esp_req |= IPSEC_PREF_UNIQUE;
   1401      0      stevel 	}
   1402      0      stevel 	if (ipp->ipp_use_se)
   1403      0      stevel 		req->ipsr_self_encap_req |= IPSEC_PREF_REQUIRED;
   1404      0      stevel 	if (ipp->ipp_use_ah)
   1405      0      stevel 		req->ipsr_ah_req |= IPSEC_PREF_REQUIRED;
   1406      0      stevel 	if (ipp->ipp_use_esp)
   1407      0      stevel 		req->ipsr_esp_req |= IPSEC_PREF_REQUIRED;
   1408      0      stevel 	return (sizeof (*req));
   1409      0      stevel }
   1410      0      stevel 
   1411      0      stevel /*
   1412      0      stevel  * Convert a new-style action back to an ipsec_req_t (more backwards compat).
   1413      0      stevel  * We assume caller has already zero'ed *req for us.
   1414      0      stevel  */
   1415      0      stevel static int
   1416      0      stevel ipsec_req_from_act(ipsec_action_t *ap, ipsec_req_t *req)
   1417      0      stevel {
   1418      0      stevel 	switch (ap->ipa_act.ipa_type) {
   1419      0      stevel 	case IPSEC_ACT_BYPASS:
   1420      0      stevel 		req->ipsr_ah_req = IPSEC_PREF_NEVER;
   1421      0      stevel 		req->ipsr_esp_req = IPSEC_PREF_NEVER;
   1422      0      stevel 		return (sizeof (*req));
   1423      0      stevel 	case IPSEC_ACT_APPLY:
   1424      0      stevel 		return (ipsec_req_from_prot(&ap->ipa_act.ipa_apply, req));
   1425      0      stevel 	}
   1426      0      stevel 	return (sizeof (*req));
   1427      0      stevel }
   1428      0      stevel 
   1429      0      stevel /*
   1430      0      stevel  * Convert a new-style action back to an ipsec_req_t (more backwards compat).
   1431      0      stevel  * We assume caller has already zero'ed *req for us.
   1432      0      stevel  */
   1433   3055      danmcd int
   1434      0      stevel ipsec_req_from_head(ipsec_policy_head_t *ph, ipsec_req_t *req, int af)
   1435      0      stevel {
   1436      0      stevel 	ipsec_policy_t *p;
   1437      0      stevel 
   1438     81    sommerfe 	/*
   1439     81    sommerfe 	 * FULL-PERSOCK: consult hash table, too?
   1440     81    sommerfe 	 */
   1441     81    sommerfe 	for (p = ph->iph_root[IPSEC_INBOUND].ipr_nonhash[af];
   1442      0      stevel 	    p != NULL;
   1443     81    sommerfe 	    p = p->ipsp_hash.hash_next) {
   1444   3055      danmcd 		if ((p->ipsp_sel->ipsl_key.ipsl_valid & IPSL_WILDCARD) == 0)
   1445      0      stevel 			return (ipsec_req_from_act(p->ipsp_act, req));
   1446      0      stevel 	}
   1447      0      stevel 	return (sizeof (*req));
   1448      0      stevel }
   1449      0      stevel 
   1450      0      stevel /*
   1451      0      stevel  * Based on per-socket or latched policy, convert to an appropriate
   1452      0      stevel  * IP_SEC_OPT ipsec_req_t for the socket option; return size so we can
   1453      0      stevel  * be tail-called from ip.
   1454      0      stevel  */
   1455      0      stevel int
   1456      0      stevel ipsec_req_from_conn(conn_t *connp, ipsec_req_t *req, int af)
   1457      0      stevel {
   1458      0      stevel 	ipsec_latch_t *ipl;
   1459      0      stevel 	int rv = sizeof (ipsec_req_t);
   1460      0      stevel 
   1461      0      stevel 	bzero(req, sizeof (*req));
   1462      0      stevel 
   1463  11042        Erik 	ASSERT(MUTEX_HELD(&connp->conn_lock));
   1464      0      stevel 	ipl = connp->conn_latch;
   1465      0      stevel 
   1466      0      stevel 	/*
   1467      0      stevel 	 * Find appropriate policy.  First choice is latched action;
   1468      0      stevel 	 * failing that, see latched policy; failing that,
   1469      0      stevel 	 * look at configured policy.
   1470      0      stevel 	 */
   1471      0      stevel 	if (ipl != NULL) {
   1472  11042        Erik 		if (connp->conn_latch_in_action != NULL) {
   1473  11042        Erik 			rv = ipsec_req_from_act(connp->conn_latch_in_action,
   1474  11042        Erik 			    req);
   1475      0      stevel 			goto done;
   1476      0      stevel 		}
   1477  11042        Erik 		if (connp->conn_latch_in_policy != NULL) {
   1478  11042        Erik 			rv = ipsec_req_from_act(
   1479  11042        Erik 			    connp->conn_latch_in_policy->ipsp_act, req);
   1480      0      stevel 			goto done;
   1481      0      stevel 		}
   1482      0      stevel 	}
   1483      0      stevel 	if (connp->conn_policy != NULL)
   1484      0      stevel 		rv = ipsec_req_from_head(connp->conn_policy, req, af);
   1485      0      stevel done:
   1486      0      stevel 	return (rv);
   1487      0      stevel }
   1488      0      stevel 
   1489      0      stevel void
   1490      0      stevel ipsec_actvec_free(ipsec_act_t *act, uint_t nact)
   1491      0      stevel {
   1492      0      stevel 	kmem_free(act, nact * sizeof (*act));
   1493      0      stevel }
   1494      0      stevel 
   1495      0      stevel /*
   1496  11042        Erik  * Consumes a reference to ipsp.
   1497      0      stevel  */
   1498      0      stevel static mblk_t *
   1499  11042        Erik ipsec_check_loopback_policy(mblk_t *data_mp, ip_recv_attr_t *ira,
   1500   3192      danmcd     ipsec_policy_t *ipsp)
   1501      0      stevel {
   1502  11042        Erik 	if (!(ira->ira_flags & IRAF_IPSEC_SECURE))
   1503  11042        Erik 		return (data_mp);
   1504  11042        Erik 
   1505  11042        Erik 	ASSERT(ira->ira_flags & IRAF_LOOPBACK);
   1506  11042        Erik 
   1507  11042        Erik 	IPPOL_REFRELE(ipsp);
   1508      0      stevel 
   1509      0      stevel 	/*
   1510      0      stevel 	 * We should do an actual policy check here.  Revisit this
   1511   3192      danmcd 	 * when we revisit the IPsec API.  (And pass a conn_t in when we
   1512   3192      danmcd 	 * get there.)
   1513      0      stevel 	 */
   1514      0      stevel 
   1515  11042        Erik 	return (data_mp);
   1516      0      stevel }
   1517      0      stevel 
   1518    691    sommerfe /*
   1519    691    sommerfe  * Check that packet's inbound ports & proto match the selectors
   1520    691    sommerfe  * expected by the SAs it traversed on the way in.
   1521    691    sommerfe  */
   1522    691    sommerfe static boolean_t
   1523  11042        Erik ipsec_check_ipsecin_unique(ip_recv_attr_t *ira, const char **reason,
   1524  11042        Erik     kstat_named_t **counter, uint64_t pkt_unique, netstack_t *ns)
   1525   3055      danmcd {
   1526   3055      danmcd 	uint64_t ah_mask, esp_mask;
   1527    983    sommerfe 	ipsa_t *ah_assoc;
   1528    983    sommerfe 	ipsa_t *esp_assoc;
   1529  11042        Erik 	ipsec_stack_t	*ipss = ns->netstack_ipsec;
   1530  11042        Erik 
   1531  11042        Erik 	ASSERT(ira->ira_flags & IRAF_IPSEC_SECURE);
   1532  11042        Erik 	ASSERT(!(ira->ira_flags & IRAF_LOOPBACK));
   1533  11042        Erik 
   1534  11042        Erik 	ah_assoc = ira->ira_ipsec_ah_sa;
   1535  11042        Erik 	esp_assoc = ira->ira_ipsec_esp_sa;
   1536    691    sommerfe 	ASSERT((ah_assoc != NULL) || (esp_assoc != NULL));
   1537    691    sommerfe 
   1538    691    sommerfe 	ah_mask = (ah_assoc != NULL) ? ah_assoc->ipsa_unique_mask : 0;
   1539    691    sommerfe 	esp_mask = (esp_assoc != NULL) ? esp_assoc->ipsa_unique_mask : 0;
   1540    691    sommerfe 
   1541    691    sommerfe 	if ((ah_mask == 0) && (esp_mask == 0))
   1542    691    sommerfe 		return (B_TRUE);
   1543    691    sommerfe 
   1544   3055      danmcd 	/*
   1545   3055      danmcd 	 * The pkt_unique check will also check for tunnel mode on the SA
   1546   3055      danmcd 	 * vs. the tunneled_packet boolean.  "Be liberal in what you receive"
   1547   3055      danmcd 	 * should not apply in this case.  ;)
   1548   3055      danmcd 	 */
   1549   3055      danmcd 
   1550   3055      danmcd 	if (ah_mask != 0 &&
   1551   3055      danmcd 	    ah_assoc->ipsa_unique_id != (pkt_unique & ah_mask)) {
   1552   3055      danmcd 		*reason = "AH inner header mismatch";
   1553   3448    dh155122 		*counter = DROPPER(ipss, ipds_spd_ah_innermismatch);
   1554   3055      danmcd 		return (B_FALSE);
   1555   3055      danmcd 	}
   1556   3055      danmcd 	if (esp_mask != 0 &&
   1557   3055      danmcd 	    esp_assoc->ipsa_unique_id != (pkt_unique & esp_mask)) {
   1558   3055      danmcd 		*reason = "ESP inner header mismatch";
   1559   3448    dh155122 		*counter = DROPPER(ipss, ipds_spd_esp_innermismatch);
   1560   3055      danmcd 		return (B_FALSE);
   1561    691    sommerfe 	}
   1562    691    sommerfe 	return (B_TRUE);
   1563    691    sommerfe }
   1564    691    sommerfe 
   1565      0      stevel static boolean_t
   1566  11042        Erik ipsec_check_ipsecin_action(ip_recv_attr_t *ira, mblk_t *mp, ipsec_action_t *ap,
   1567  11042        Erik     ipha_t *ipha, ip6_t *ip6h, const char **reason, kstat_named_t **counter,
   1568  11042        Erik     netstack_t *ns)
   1569      0      stevel {
   1570      0      stevel 	boolean_t ret = B_TRUE;
   1571      0      stevel 	ipsec_prot_t *ipp;
   1572      0      stevel 	ipsa_t *ah_assoc;
   1573      0      stevel 	ipsa_t *esp_assoc;
   1574      0      stevel 	boolean_t decaps;
   1575   3448    dh155122 	ipsec_stack_t	*ipss = ns->netstack_ipsec;
   1576      0      stevel 
   1577      0      stevel 	ASSERT((ipha == NULL && ip6h != NULL) ||
   1578      0      stevel 	    (ip6h == NULL && ipha != NULL));
   1579      0      stevel 
   1580  11042        Erik 	if (ira->ira_flags & IRAF_LOOPBACK) {
   1581      0      stevel 		/*
   1582      0      stevel 		 * Besides accepting pointer-equivalent actions, we also
   1583      0      stevel 		 * accept any ICMP errors we generated for ourselves,
   1584      0      stevel 		 * regardless of policy.  If we do not wish to make this
   1585      0      stevel 		 * assumption in the future, check here, and where
   1586  11042        Erik 		 * IXAF_TRUSTED_ICMP is initialized in ip.c and ip6.c.
   1587  11042        Erik 		 */
   1588  11042        Erik 		if (ap == ira->ira_ipsec_action ||
   1589  11042        Erik 		    (ira->ira_flags & IRAF_TRUSTED_ICMP))
   1590      0      stevel 			return (B_TRUE);
   1591      0      stevel 
   1592      0      stevel 		/* Deep compare necessary here?? */
   1593   3448    dh155122 		*counter = DROPPER(ipss, ipds_spd_loopback_mismatch);
   1594      0      stevel 		*reason = "loopback policy mismatch";
   1595      0      stevel 		return (B_FALSE);
   1596      0      stevel 	}
   1597  11042        Erik 	ASSERT(!(ira->ira_flags & IRAF_TRUSTED_ICMP));
   1598  11042        Erik 	ASSERT(ira->ira_flags & IRAF_IPSEC_SECURE);
   1599  11042        Erik 
   1600  11042        Erik 	ah_assoc = ira->ira_ipsec_ah_sa;
   1601  11042        Erik 	esp_assoc = ira->ira_ipsec_esp_sa;
   1602  11042        Erik 
   1603  11042        Erik 	decaps = (ira->ira_flags & IRAF_IPSEC_DECAPS);
   1604      0      stevel 
   1605      0      stevel 	switch (ap->ipa_act.ipa_type) {
   1606      0      stevel 	case IPSEC_ACT_DISCARD:
   1607      0      stevel 	case IPSEC_ACT_REJECT:
   1608      0      stevel 		/* Should "fail hard" */
   1609   3448    dh155122 		*counter = DROPPER(ipss, ipds_spd_explicit);
   1610      0      stevel 		*reason = "blocked by policy";
   1611      0      stevel 		return (B_FALSE);
   1612      0      stevel 
   1613      0      stevel 	case IPSEC_ACT_BYPASS:
   1614      0      stevel 	case IPSEC_ACT_CLEAR:
   1615   3448    dh155122 		*counter = DROPPER(ipss, ipds_spd_got_secure);
   1616      0      stevel 		*reason = "expected clear, got protected";
   1617      0      stevel 		return (B_FALSE);
   1618      0      stevel 
   1619      0      stevel 	case IPSEC_ACT_APPLY:
   1620      0      stevel 		ipp = &ap->ipa_act.ipa_apply;
   1621      0      stevel 		/*
   1622      0      stevel 		 * As of now we do the simple checks of whether
   1623      0      stevel 		 * the datagram has gone through the required IPSEC
   1624      0      stevel 		 * protocol constraints or not. We might have more
   1625      0      stevel 		 * in the future like sensitive levels, key bits, etc.
   1626      0      stevel 		 * If it fails the constraints, check whether we would
   1627      0      stevel 		 * have accepted this if it had come in clear.
   1628      0      stevel 		 */
   1629      0      stevel 		if (ipp->ipp_use_ah) {
   1630      0      stevel 			if (ah_assoc == NULL) {
   1631      0      stevel 				ret = ipsec_inbound_accept_clear(mp, ipha,
   1632      0      stevel 				    ip6h);
   1633   3448    dh155122 				*counter = DROPPER(ipss, ipds_spd_got_clear);
   1634      0      stevel 				*reason = "unprotected not accepted";
   1635      0      stevel 				break;
   1636      0      stevel 			}
   1637      0      stevel 			ASSERT(ah_assoc != NULL);
   1638      0      stevel 			ASSERT(ipp->ipp_auth_alg != 0);
   1639      0      stevel 
   1640      0      stevel 			if (ah_assoc->ipsa_auth_alg !=
   1641      0      stevel 			    ipp->ipp_auth_alg) {
   1642   3448    dh155122 				*counter = DROPPER(ipss, ipds_spd_bad_ahalg);
   1643      0      stevel 				*reason = "unacceptable ah alg";
   1644      0      stevel 				ret = B_FALSE;
   1645      0      stevel 				break;
   1646      0      stevel 			}
   1647      0      stevel 		} else if (ah_assoc != NULL) {
   1648      0      stevel 			/*
   1649      0      stevel 			 * Don't allow this. Check IPSEC NOTE above
   1650      0      stevel 			 * ip_fanout_proto().
   1651      0      stevel 			 */
   1652   3448    dh155122 			*counter = DROPPER(ipss, ipds_spd_got_ah);
   1653      0      stevel 			*reason = "unexpected AH";
   1654      0      stevel 			ret = B_FALSE;
   1655      0      stevel 			break;
   1656      0      stevel 		}
   1657      0      stevel 		if (ipp->ipp_use_esp) {
   1658      0      stevel 			if (esp_assoc == NULL) {
   1659      0      stevel 				ret = ipsec_inbound_accept_clear(mp, ipha,
   1660      0      stevel 				    ip6h);
   1661   3448    dh155122 				*counter = DROPPER(ipss, ipds_spd_got_clear);
   1662      0      stevel 				*reason = "unprotected not accepted";
   1663      0      stevel 				break;
   1664      0      stevel 			}
   1665      0      stevel 			ASSERT(esp_assoc != NULL);
   1666      0      stevel 			ASSERT(ipp->ipp_encr_alg != 0);
   1667      0      stevel 
   1668      0      stevel 			if (esp_assoc->ipsa_encr_alg !=
   1669      0      stevel 			    ipp->ipp_encr_alg) {
   1670   3448    dh155122 				*counter = DROPPER(ipss, ipds_spd_bad_espealg);
   1671      0      stevel 				*reason = "unacceptable esp alg";
   1672      0      stevel 				ret = B_FALSE;
   1673      0      stevel 				break;
   1674      0      stevel 			}
   1675      0      stevel 			/*
   1676      0      stevel 			 * If the client does not need authentication,
   1677      0      stevel 			 * we don't verify the alogrithm.
   1678      0      stevel 			 */
   1679      0      stevel 			if (ipp->ipp_use_espa) {
   1680      0      stevel 				if (esp_assoc->ipsa_auth_alg !=
   1681      0      stevel 				    ipp->ipp_esp_auth_alg) {
   1682   3448    dh155122 					*counter = DROPPER(ipss,
   1683   3448    dh155122 					    ipds_spd_bad_espaalg);
   1684      0      stevel 					*reason = "unacceptable esp auth alg";
   1685      0      stevel 					ret = B_FALSE;
   1686      0      stevel 					break;
   1687      0      stevel 				}
   1688      0      stevel 			}
   1689      0      stevel 		} else if (esp_assoc != NULL) {
   1690  11042        Erik 			/*
   1691  11042        Erik 			 * Don't allow this. Check IPSEC NOTE above
   1692  11042        Erik 			 * ip_fanout_proto().
   1693  11042        Erik 			 */
   1694   3448    dh155122 			*counter = DROPPER(ipss, ipds_spd_got_esp);
   1695      0      stevel 			*reason = "unexpected ESP";
   1696      0      stevel 			ret = B_FALSE;
   1697      0      stevel 			break;
   1698      0      stevel 		}
   1699      0      stevel 		if (ipp->ipp_use_se) {
   1700      0      stevel 			if (!decaps) {
   1701      0      stevel 				ret = ipsec_inbound_accept_clear(mp, ipha,
   1702      0      stevel 				    ip6h);
   1703      0      stevel 				if (!ret) {
   1704      0      stevel 					/* XXX mutant? */
   1705   3448    dh155122 					*counter = DROPPER(ipss,
   1706   3448    dh155122 					    ipds_spd_bad_selfencap);
   1707      0      stevel 					*reason = "self encap not found";
   1708      0      stevel 					break;
   1709      0      stevel 				}
   1710      0      stevel 			}
   1711      0      stevel 		} else if (decaps) {
   1712      0      stevel 			/*
   1713      0      stevel 			 * XXX If the packet comes in tunneled and the
   1714      0      stevel 			 * recipient does not expect it to be tunneled, it
   1715      0      stevel 			 * is okay. But we drop to be consistent with the
   1716      0      stevel 			 * other cases.
   1717      0      stevel 			 */
   1718   3448    dh155122 			*counter = DROPPER(ipss, ipds_spd_got_selfencap);
   1719      0      stevel 			*reason = "unexpected self encap";
   1720      0      stevel 			ret = B_FALSE;
   1721      0      stevel 			break;
   1722      0      stevel 		}
   1723  11042        Erik 		if (ira->ira_ipsec_action != NULL) {
   1724      0      stevel 			/*
   1725      0      stevel 			 * This can happen if we do a double policy-check on
   1726      0      stevel 			 * a packet
   1727      0      stevel 			 * XXX XXX should fix this case!
   1728      0      stevel 			 */
   1729  11042        Erik 			IPACT_REFRELE(ira->ira_ipsec_action);
   1730  11042        Erik 		}
   1731  11042        Erik 		ASSERT(ira->ira_flags & IRAF_IPSEC_SECURE);
   1732  11042        Erik 		ASSERT(ira->ira_ipsec_action == NULL);
   1733      0      stevel 		IPACT_REFHOLD(ap);
   1734  11042        Erik 		ira->ira_ipsec_action = ap;
   1735      0      stevel 		break;	/* from switch */
   1736      0      stevel 	}
   1737      0      stevel 	return (ret);
   1738      0      stevel }
   1739      0      stevel 
   1740      0      stevel static boolean_t
   1741      0      stevel spd_match_inbound_ids(ipsec_latch_t *ipl, ipsa_t *sa)
   1742      0      stevel {
   1743      0      stevel 	ASSERT(ipl->ipl_ids_latched == B_TRUE);
   1744      0      stevel 	return ipsid_equal(ipl->ipl_remote_cid, sa->ipsa_src_cid) &&
   1745      0      stevel 	    ipsid_equal(ipl->ipl_local_cid, sa->ipsa_dst_cid);
   1746      0      stevel }
   1747      0      stevel 
   1748      0      stevel /*
   1749   3055      danmcd  * Takes a latched conn and an inbound packet and returns a unique_id suitable
   1750   3055      danmcd  * for SA comparisons.  Most of the time we will copy from the conn_t, but
   1751   3055      danmcd  * there are cases when the conn_t is latched but it has wildcard selectors,
   1752   3055      danmcd  * and then we need to fallback to scooping them out of the packet.
   1753   3055      danmcd  *
   1754   3055      danmcd  * Assume we'll never have 0 with a conn_t present, so use 0 as a failure.  We
   1755   3055      danmcd  * can get away with this because we only have non-zero ports/proto for
   1756   3055      danmcd  * latched conn_ts.
   1757   3055      danmcd  *
   1758   3055      danmcd  * Ideal candidate for an "inline" keyword, as we're JUST convoluted enough
   1759   3055      danmcd  * to not be a nice macro.
   1760   3055      danmcd  */
   1761   3055      danmcd static uint64_t
   1762   3055      danmcd conn_to_unique(conn_t *connp, mblk_t *data_mp, ipha_t *ipha, ip6_t *ip6h)
   1763   3055      danmcd {
   1764   3055      danmcd 	ipsec_selector_t sel;
   1765  11042        Erik 	uint8_t ulp = connp->conn_proto;
   1766  11042        Erik 
   1767  11042        Erik 	ASSERT(connp->conn_latch_in_policy != NULL);
   1768   3055      danmcd 
   1769   3055      danmcd 	if ((ulp == IPPROTO_TCP || ulp == IPPROTO_UDP || ulp == IPPROTO_SCTP) &&
   1770   3055      danmcd 	    (connp->conn_fport == 0 || connp->conn_lport == 0)) {
   1771   3055      danmcd 		/* Slow path - we gotta grab from the packet. */
   1772   3055      danmcd 		if (ipsec_init_inbound_sel(&sel, data_mp, ipha, ip6h,
   1773   5245      danmcd 		    SEL_NONE) != SELRET_SUCCESS) {
   1774   3055      danmcd 			/* Failure -> have caller free packet with ENOMEM. */
   1775   3055      danmcd 			return (0);
   1776   3055      danmcd 		}
   1777   3055      danmcd 		return (SA_UNIQUE_ID(sel.ips_remote_port, sel.ips_local_port,
   1778   5245      danmcd 		    sel.ips_protocol, 0));
   1779   3055      danmcd 	}
   1780   3055      danmcd 
   1781   3055      danmcd #ifdef DEBUG_NOT_UNTIL_6478464
   1782   3055      danmcd 	if (ipsec_init_inbound_sel(&sel, data_mp, ipha, ip6h, SEL_NONE) ==
   1783   3055      danmcd 	    SELRET_SUCCESS) {
   1784   3055      danmcd 		ASSERT(sel.ips_local_port == connp->conn_lport);
   1785   3055      danmcd 		ASSERT(sel.ips_remote_port == connp->conn_fport);
   1786  11042        Erik 		ASSERT(sel.ips_protocol == connp->conn_proto);
   1787  11042        Erik 	}
   1788  11042        Erik 	ASSERT(connp->conn_proto != 0);
   1789   3055      danmcd #endif
   1790   3055      danmcd 
   1791   3055      danmcd 	return (SA_UNIQUE_ID(connp->conn_fport, connp->conn_lport, ulp, 0));
   1792   3055      danmcd }
   1793   3055      danmcd 
   1794   3055      danmcd /*
   1795  11042        Erik  * Called to check policy on a latched connection.
   1796  11042        Erik  * Note that we don't dereference conn_latch or conn_ihere since the conn might
   1797  11042        Erik  * be closing. The caller passes a held ipsec_latch_t instead.
   1798  11042        Erik  */
   1799  11042        Erik static boolean_t
   1800  11042        Erik ipsec_check_ipsecin_latch(ip_recv_attr_t *ira, mblk_t *mp, ipsec_latch_t *ipl,
   1801  11042        Erik     ipsec_action_t *ap, ipha_t *ipha, ip6_t *ip6h, const char **reason,
   1802  11042        Erik     kstat_named_t **counter, conn_t *connp, netstack_t *ns)
   1803  11042        Erik {
   1804   3448    dh155122 	ipsec_stack_t	*ipss = ns->netstack_ipsec;
   1805   3448    dh155122 
   1806      0      stevel 	ASSERT(ipl->ipl_ids_latched == B_TRUE);
   1807  11042        Erik 	ASSERT(ira->ira_flags & IRAF_IPSEC_SECURE);
   1808  11042        Erik 
   1809  11042        Erik 	if (!(ira->ira_flags & IRAF_LOOPBACK)) {
   1810    983    sommerfe 		/*
   1811    983    sommerfe 		 * Over loopback, there aren't real security associations,
   1812    983    sommerfe 		 * so there are neither identities nor "unique" values
   1813    983    sommerfe 		 * for us to check the packet against.
   1814    983    sommerfe 		 */
   1815  11042        Erik 		if (ira->ira_ipsec_ah_sa != NULL) {
   1816  11042        Erik 			if (!spd_match_inbound_ids(ipl,
   1817  11042        Erik 			    ira->ira_ipsec_ah_sa)) {
   1818  11042        Erik 				*counter = DROPPER(ipss, ipds_spd_ah_badid);
   1819  11042        Erik 				*reason = "AH identity mismatch";
   1820  11042        Erik 				return (B_FALSE);
   1821  11042        Erik 			}
   1822  11042        Erik 		}
   1823  11042        Erik 
   1824  11042        Erik 		if (ira->ira_ipsec_esp_sa != NULL) {
   1825  11042        Erik 			if (!spd_match_inbound_ids(ipl,
   1826  11042        Erik 			    ira->ira_ipsec_esp_sa)) {
   1827  11042        Erik 				*counter = DROPPER(ipss, ipds_spd_esp_badid);
   1828  11042        Erik 				*reason = "ESP identity mismatch";
   1829  11042        Erik 				return (B_FALSE);
   1830  11042        Erik 			}
   1831    983    sommerfe 		}
   1832    983    sommerfe 
   1833   3055      danmcd 		/*
   1834   3055      danmcd 		 * Can fudge pkt_unique from connp because we're latched.
   1835   3055      danmcd 		 * In DEBUG kernels (see conn_to_unique()'s implementation),
   1836   3055      danmcd 		 * verify this even if it REALLY slows things down.
   1837   3055      danmcd 		 */
   1838  11042        Erik 		if (!ipsec_check_ipsecin_unique(ira, reason, counter,
   1839  11042        Erik 		    conn_to_unique(connp, mp, ipha, ip6h), ns)) {
   1840  11042        Erik 			return (B_FALSE);
   1841  11042        Erik 		}
   1842  11042        Erik 	}
   1843  11042        Erik 	return (ipsec_check_ipsecin_action(ira, mp, ap, ipha, ip6h, reason,
   1844  11042        Erik 	    counter, ns));
   1845      0      stevel }
   1846      0      stevel 
   1847      0      stevel /*
   1848      0      stevel  * Check to see whether this secured datagram meets the policy
   1849      0      stevel  * constraints specified in ipsp.
   1850      0      stevel  *
   1851      0      stevel  * Called from ipsec_check_global_policy, and ipsec_check_inbound_policy.
   1852      0      stevel  *
   1853      0      stevel  * Consumes a reference to ipsp.
   1854  11042        Erik  * Returns the mblk if ok.
   1855      0      stevel  */
   1856      0      stevel static mblk_t *
   1857  11042        Erik ipsec_check_ipsecin_policy(mblk_t *data_mp, ipsec_policy_t *ipsp,
   1858  11042        Erik     ipha_t *ipha, ip6_t *ip6h, uint64_t pkt_unique, ip_recv_attr_t *ira,
   1859  11042        Erik     netstack_t *ns)
   1860  11042        Erik {
   1861      0      stevel 	ipsec_action_t *ap;
   1862      0      stevel 	const char *reason = "no policy actions found";
   1863   3448    dh155122 	ip_stack_t	*ipst = ns->netstack_ip;
   1864  11042        Erik 	ipsec_stack_t	*ipss = ns->netstack_ipsec;
   1865   3448    dh155122 	kstat_named_t *counter;
   1866   3448    dh155122 
   1867   3448    dh155122 	counter = DROPPER(ipss, ipds_spd_got_secure);
   1868      0      stevel 
   1869      0      stevel 	ASSERT(ipsp != NULL);
   1870      0      stevel 
   1871      0      stevel 	ASSERT((ipha == NULL && ip6h != NULL) ||
   1872      0      stevel 	    (ip6h == NULL && ipha != NULL));
   1873      0      stevel 
   1874  11042        Erik 	if (ira->ira_flags & IRAF_LOOPBACK)
   1875  11042        Erik 		return (ipsec_check_loopback_policy(data_mp, ira, ipsp));
   1876  11042        Erik 
   1877  11042        Erik 	ASSERT(ira->ira_flags & IRAF_IPSEC_SECURE);
   1878  11042        Erik 
   1879  11042        Erik 	if (ira->ira_ipsec_action != NULL) {
   1880      0      stevel 		/*
   1881      0      stevel 		 * this can happen if we do a double policy-check on a packet
   1882      0      stevel 		 * Would be nice to be able to delete this test..
   1883      0      stevel 		 */
   1884  11042        Erik 		IPACT_REFRELE(ira->ira_ipsec_action);
   1885  11042        Erik 	}
   1886  11042        Erik 	ASSERT(ira->ira_ipsec_action == NULL);
   1887  11042        Erik 
   1888  11042        Erik 	if (!SA_IDS_MATCH(ira->ira_ipsec_ah_sa, ira->ira_ipsec_esp_sa)) {
   1889      0      stevel 		reason = "inbound AH and ESP identities differ";
   1890   3448    dh155122 		counter = DROPPER(ipss, ipds_spd_ahesp_diffid);
   1891      0      stevel 		goto drop;
   1892      0      stevel 	}
   1893    691    sommerfe 
   1894  11042        Erik 	if (!ipsec_check_ipsecin_unique(ira, &reason, &counter, pkt_unique,
   1895  11042        Erik 	    ns))
   1896    691    sommerfe 		goto drop;
   1897      0      stevel 
   1898      0      stevel 	/*
   1899      0      stevel 	 * Ok, now loop through the possible actions and see if any
   1900      0      stevel 	 * of them work for us.
   1901      0      stevel 	 */
   1902      0      stevel 
   1903      0      stevel 	for (ap = ipsp->ipsp_act; ap != NULL; ap = ap->ipa_next) {
   1904  11042        Erik 		if (ipsec_check_ipsecin_action(ira, data_mp, ap,
   1905  11042        Erik 		    ipha, ip6h, &reason, &counter, ns)) {
   1906   3448    dh155122 			BUMP_MIB(&ipst->ips_ip_mib, ipsecInSucceeded);
   1907  11042        Erik 			IPPOL_REFRELE(ipsp);
   1908  11042        Erik 			return (data_mp);
   1909      0      stevel 		}
   1910      0      stevel 	}
   1911      0      stevel drop:
   1912   3448    dh155122 	ipsec_rl_strlog(ns, IP_MOD_ID, 0, 0, SL_ERROR|SL_WARN|SL_CONSOLE,
   1913      0      stevel 	    "ipsec inbound policy mismatch: %s, packet dropped\n",
   1914      0      stevel 	    reason);
   1915  11042        Erik 	IPPOL_REFRELE(ipsp);
   1916  11042        Erik 	ASSERT(ira->ira_ipsec_action == NULL);
   1917   3448    dh155122 	BUMP_MIB(&ipst->ips_ip_mib, ipsecInFailed);
   1918  11042        Erik 	ip_drop_packet(data_mp, B_TRUE, NULL, counter,
   1919   3448    dh155122 	    &ipss->ipsec_spd_dropper);
   1920      0      stevel 	return (NULL);
   1921      0      stevel }
   1922      0      stevel 
   1923      0      stevel /*
   1924      0      stevel  * sleazy prefix-length-based compare.
   1925      0      stevel  * another inlining candidate..
   1926      0      stevel  */
   1927   3055      danmcd boolean_t
   1928      0      stevel ip_addr_match(uint8_t *addr1, int pfxlen, in6_addr_t *addr2p)
   1929      0      stevel {
   1930      0      stevel 	int offset = pfxlen>>3;
   1931      0      stevel 	int bitsleft = pfxlen & 7;
   1932      0      stevel 	uint8_t *addr2 = (uint8_t *)addr2p;
   1933      0      stevel 
   1934      0      stevel 	/*
   1935      0      stevel 	 * and there was much evil..
   1936      0      stevel 	 * XXX should inline-expand the bcmp here and do this 32 bits
   1937      0      stevel 	 * or 64 bits at a time..
   1938      0      stevel 	 */
   1939      0      stevel 	return ((bcmp(addr1, addr2, offset) == 0) &&
   1940      0      stevel 	    ((bitsleft == 0) ||
   1941   5245      danmcd 	    (((addr1[offset] ^ addr2[offset]) & (0xff<<(8-bitsleft))) == 0)));
   1942      0      stevel }
   1943      0      stevel 
   1944     81    sommerfe static ipsec_policy_t *
   1945     81    sommerfe ipsec_find_policy_chain(ipsec_policy_t *best, ipsec_policy_t *chain,
   1946     81    sommerfe     ipsec_selector_t *sel, boolean_t is_icmp_inv_acq)
   1947     81    sommerfe {
   1948     81    sommerfe 	ipsec_selkey_t *isel;
   1949     81    sommerfe 	ipsec_policy_t *p;
   1950     81    sommerfe 	int bpri = best ? best->ipsp_prio : 0;
   1951     81    sommerfe 
   1952     81    sommerfe 	for (p = chain; p != NULL; p = p->ipsp_hash.hash_next) {
   1953     81    sommerfe 		uint32_t valid;
   1954     81    sommerfe 
   1955     81    sommerfe 		if (p->ipsp_prio <= bpri)
   1956     81    sommerfe 			continue;
   1957     81    sommerfe 		isel = &p->ipsp_sel->ipsl_key;
   1958     81    sommerfe 		valid = isel->ipsl_valid;
   1959     81    sommerfe 
   1960     81    sommerfe 		if ((valid & IPSL_PROTOCOL) &&
   1961     81    sommerfe 		    (isel->ipsl_proto != sel->ips_protocol))
   1962     81    sommerfe 			continue;
   1963     81    sommerfe 
   1964     81    sommerfe 		if ((valid & IPSL_REMOTE_ADDR) &&
   1965     81    sommerfe 		    !ip_addr_match((uint8_t *)&isel->ipsl_remote,
   1966   5245      danmcd 		    isel->ipsl_remote_pfxlen, &sel->ips_remote_addr_v6))
   1967     81    sommerfe 			continue;
   1968     81    sommerfe 
   1969     81    sommerfe 		if ((valid & IPSL_LOCAL_ADDR) &&
   1970     81    sommerfe 		    !ip_addr_match((uint8_t *)&isel->ipsl_local,
   1971   5245      danmcd 		    isel->ipsl_local_pfxlen, &sel->ips_local_addr_v6))
   1972     81    sommerfe 			continue;
   1973     81    sommerfe 
   1974     81    sommerfe 		if ((valid & IPSL_REMOTE_PORT) &&
   1975     81    sommerfe 		    isel->ipsl_rport != sel->ips_remote_port)
   1976     81    sommerfe 			continue;
   1977     81    sommerfe 
   1978     81    sommerfe 		if ((valid & IPSL_LOCAL_PORT) &&
   1979     81    sommerfe 		    isel->ipsl_lport != sel->ips_local_port)
   1980     81    sommerfe 			continue;
   1981     81    sommerfe 
   1982     81    sommerfe 		if (!is_icmp_inv_acq) {
   1983     81    sommerfe 			if ((valid & IPSL_ICMP_TYPE) &&
   1984     81    sommerfe 			    (isel->ipsl_icmp_type > sel->ips_icmp_type ||
   1985     81    sommerfe 			    isel->ipsl_icmp_type_end < sel->ips_icmp_type)) {
   1986     81    sommerfe 				continue;
   1987     81    sommerfe 			}
   1988     81    sommerfe 
   1989     81    sommerfe 			if ((valid & IPSL_ICMP_CODE) &&
   1990     81    sommerfe 			    (isel->ipsl_icmp_code > sel->ips_icmp_code ||
   1991     81    sommerfe 			    isel->ipsl_icmp_code_end <
   1992     81    sommerfe 			    sel->ips_icmp_code)) {
   1993     81    sommerfe 				continue;
   1994     81    sommerfe 			}
   1995     81    sommerfe 		} else {
   1996     81    sommerfe 			/*
   1997     81    sommerfe 			 * special case for icmp inverse acquire
   1998     81    sommerfe 			 * we only want policies that aren't drop/pass
   1999     81    sommerfe 			 */
   2000     81    sommerfe 			if (p->ipsp_act->ipa_act.ipa_type != IPSEC_ACT_APPLY)
   2001     81    sommerfe 				continue;
   2002     81    sommerfe 		}
   2003     81    sommerfe 
   2004     81    sommerfe 		/* we matched all the packet-port-field selectors! */
   2005     81    sommerfe 		best = p;
   2006     81    sommerfe 		bpri = p->ipsp_prio;
   2007     81    sommerfe 	}
   2008     81    sommerfe 
   2009     81    sommerfe 	return (best);
   2010     81    sommerfe }
   2011     81    sommerfe 
   2012      0      stevel /*
   2013      0      stevel  * Try to find and return the best policy entry under a given policy
   2014      0      stevel  * root for a given set of selectors; the first parameter "best" is
   2015      0      stevel  * the current best policy so far.  If "best" is non-null, we have a
   2016      0      stevel  * reference to it.  We return a reference to a policy; if that policy
   2017      0      stevel  * is not the original "best", we need to release that reference
   2018      0      stevel  * before returning.
   2019      0      stevel  */
   2020   3055      danmcd ipsec_policy_t *
   2021   3055      danmcd ipsec_find_policy_head(ipsec_policy_t *best, ipsec_policy_head_t *head,
   2022  11042        Erik     int direction, ipsec_selector_t *sel)
   2023     81    sommerfe {
   2024     81    sommerfe 	ipsec_policy_t *curbest;
   2025      0      stevel 	ipsec_policy_root_t *root;
   2026      0      stevel 	uint8_t is_icmp_inv_acq = sel->ips_is_icmp_inv_acq;
   2027      0      stevel 	int af = sel->ips_isv4 ? IPSEC_AF_V4 : IPSEC_AF_V6;
   2028      0      stevel 
   2029      0      stevel 	curbest = best;
   2030      0      stevel 	root = &head->iph_root[direction];
   2031      0      stevel 
   2032      0      stevel #ifdef DEBUG
   2033      0      stevel 	if (is_icmp_inv_acq) {
   2034      0      stevel 		if (sel->ips_isv4) {
   2035      0      stevel 			if (sel->ips_protocol != IPPROTO_ICMP) {
   2036   5245      danmcd 				cmn_err(CE_WARN, "ipsec_find_policy_head:"
   2037   5245      danmcd 				    " expecting icmp, got %d",
   2038   5245      danmcd 				    sel->ips_protocol);
   2039      0      stevel 			}
   2040      0      stevel 		} else {
   2041     81    sommerfe 			if (sel->ips_protocol != IPPROTO_ICMPV6) {
   2042      0      stevel 				cmn_err(CE_WARN, "ipsec_find_policy_head:"
   2043   5245      danmcd 				    " expecting icmpv6, got %d",
   2044   5245      danmcd 				    sel->ips_protocol);
   2045      0      stevel 			}
   2046      0      stevel 		}
   2047      0      stevel 	}
   2048      0      stevel #endif
   2049      0      stevel 
   2050      0      stevel 	rw_enter(&head->iph_lock, RW_READER);
   2051      0      stevel 
   2052     81    sommerfe 	if (root->ipr_nchains > 0) {
   2053     81    sommerfe 		curbest = ipsec_find_policy_chain(curbest,
   2054   3055      danmcd 		    root->ipr_hash[selector_hash(sel, root)].hash_head, sel,
   2055   3055      danmcd 		    is_icmp_inv_acq);
   2056     81    sommerfe 	}
   2057     81    sommerfe 	curbest = ipsec_find_policy_chain(curbest, root->ipr_nonhash[af], sel,
   2058     81    sommerfe 	    is_icmp_inv_acq);
   2059     81    sommerfe 
   2060     81    sommerfe 	/*
   2061     81    sommerfe 	 * Adjust reference counts if we found anything new.
   2062      0      stevel 	 */
   2063      0      stevel 	if (curbest != best) {
   2064     81    sommerfe 		ASSERT(curbest != NULL);
   2065     81    sommerfe 		IPPOL_REFHOLD(curbest);
   2066     81    sommerfe 
   2067      0      stevel 		if (best != NULL) {
   2068  11042        Erik 			IPPOL_REFRELE(best);
   2069      0      stevel 		}
   2070      0      stevel 	}
   2071      0      stevel 
   2072      0      stevel 	rw_exit(&head->iph_lock);
   2073      0      stevel 
   2074      0      stevel 	return (curbest);
   2075      0      stevel }
   2076      0      stevel 
   2077      0      stevel /*
   2078      0      stevel  * Find the best system policy (either global or per-interface) which
   2079      0      stevel  * applies to the given selector; look in all the relevant policy roots
   2080      0      stevel  * to figure out which policy wins.
   2081      0      stevel  *
   2082      0      stevel  * Returns a reference to a policy; caller must release this
   2083      0      stevel  * reference when done.
   2084      0      stevel  */
   2085      0      stevel ipsec_policy_t *
   2086  11042        Erik ipsec_find_policy(int direction, const conn_t *connp, ipsec_selector_t *sel,
   2087  11042        Erik     netstack_t *ns)
   2088      0      stevel {
   2089      0      stevel 	ipsec_policy_t *p;
   2090   3448    dh155122 	ipsec_stack_t	*ipss = ns->netstack_ipsec;
   2091   3448    dh155122 
   2092   3448    dh155122 	p = ipsec_find_policy_head(NULL, &ipss->ipsec_system_policy,
   2093  11042        Erik 	    direction, sel);
   2094      0      stevel 	if ((connp != NULL) && (connp->conn_policy != NULL)) {
   2095      0      stevel 		p = ipsec_find_policy_head(p, connp->conn_policy,
   2096  11042        Erik 		    direction, sel);
   2097      0      stevel 	}
   2098      0      stevel 
   2099      0      stevel 	return (p);
   2100      0      stevel }
   2101      0      stevel 
   2102      0      stevel /*
   2103      0      stevel  * Check with global policy and see whether this inbound
   2104      0      stevel  * packet meets the policy constraints.
   2105      0      stevel  *
   2106      0      stevel  * Locate appropriate policy from global policy, supplemented by the
   2107      0      stevel  * conn's configured and/or cached policy if the conn is supplied.
   2108      0      stevel  *
   2109      0      stevel  * Dispatch to ipsec_check_ipsecin_policy if we have policy and an
   2110      0      stevel  * encrypted packet to see if they match.
   2111      0      stevel  *
   2112      0      stevel  * Otherwise, see if the policy allows cleartext; if not, drop it on the
   2113      0      stevel  * floor.
   2114      0      stevel  */
   2115      0      stevel mblk_t *
   2116  11042        Erik ipsec_check_global_policy(mblk_t *data_mp, conn_t *connp,
   2117  11042        Erik     ipha_t *ipha, ip6_t *ip6h, ip_recv_attr_t *ira, netstack_t *ns)
   2118      0      stevel {
   2119      0      stevel 	ipsec_policy_t *p;
   2120      0      stevel 	ipsec_selector_t sel;
   2121      0      stevel 	boolean_t policy_present;
   2122      0      stevel 	kstat_named_t *counter;
   2123   3055      danmcd 	uint64_t pkt_unique;
   2124   3448    dh155122 	ip_stack_t	*ipst = ns->netstack_ip;
   2125  11042        Erik 	ipsec_stack_t	*ipss = ns->netstack_ipsec;
   2126      0      stevel 
   2127      0      stevel 	sel.ips_is_icmp_inv_acq = 0;
   2128      0      stevel 
   2129      0      stevel 	ASSERT((ipha == NULL && ip6h != NULL) ||
   2130      0      stevel 	    (ip6h == NULL && ipha != NULL));
   2131      0      stevel 
   2132      0      stevel 	if (ipha != NULL)
   2133   3448    dh155122 		policy_present = ipss->ipsec_inbound_v4_policy_present;
   2134      0      stevel 	else
   2135   3448    dh155122 		policy_present = ipss->ipsec_inbound_v6_policy_present;
   2136      0      stevel 
   2137      0      stevel 	if (!policy_present && connp == NULL) {
   2138      0      stevel 		/*
   2139      0      stevel 		 * No global policy and no per-socket policy;
   2140      0      stevel 		 * just pass it back (but we shouldn't get here in that case)
   2141      0      stevel 		 */
   2142  11042        Erik 		return (data_mp);
   2143      0      stevel 	}
   2144      0      stevel 
   2145      0      stevel 	/*
   2146      0      stevel 	 * If we have cached policy, use it.
   2147      0      stevel 	 * Otherwise consult system policy.
   2148      0      stevel 	 */
   2149      0      stevel 	if ((connp != NULL) && (connp->conn_latch != NULL)) {
   2150  11042        Erik 		p = connp->conn_latch_in_policy;
   2151      0      stevel 		if (p != NULL) {
   2152      0      stevel 			IPPOL_REFHOLD(p);
   2153  10934  sommerfeld 		}
   2154  10934  sommerfeld 		/*
   2155   3055      danmcd 		 * Fudge sel for UNIQUE_ID setting below.
   2156   3055      danmcd 		 */
   2157   3055      danmcd 		pkt_unique = conn_to_unique(connp, data_mp, ipha, ip6h);
   2158      0      stevel 	} else {
   2159      0      stevel 		/* Initialize the ports in the selector */
   2160   3055      danmcd 		if (ipsec_init_inbound_sel(&sel, data_mp, ipha, ip6h,
   2161   5245      danmcd 		    SEL_NONE) == SELRET_NOMEM) {
   2162      0      stevel 			/*
   2163      0      stevel 			 * Technically not a policy mismatch, but it is
   2164      0      stevel 			 * an internal failure.
   2165      0      stevel 			 */
   2166   3192      danmcd 			ipsec_log_policy_failure(IPSEC_POLICY_MISMATCH,
   2167  10934  sommerfeld 			    "ipsec_init_inbound_sel", ipha, ip6h, B_TRUE, ns);
   2168   3448    dh155122 			counter = DROPPER(ipss, ipds_spd_nomem);
   2169      0      stevel 			goto fail;
   2170      0      stevel 		}
   2171      0      stevel 
   2172      0      stevel 		/*
   2173      0      stevel 		 * Find the policy which best applies.
   2174      0      stevel 		 *
   2175      0      stevel 		 * If we find global policy, we should look at both
   2176      0      stevel 		 * local policy and global policy and see which is
   2177      0      stevel 		 * stronger and match accordingly.
   2178      0      stevel 		 *
   2179      0      stevel 		 * If we don't find a global policy, check with
   2180      0      stevel 		 * local policy alone.
   2181      0      stevel 		 */
   2182      0      stevel 
   2183  11042        Erik 		p = ipsec_find_policy(IPSEC_TYPE_INBOUND, connp, &sel, ns);
   2184   3055      danmcd 		pkt_unique = SA_UNIQUE_ID(sel.ips_remote_port,
   2185   3055      danmcd 		    sel.ips_local_port, sel.ips_protocol, 0);
   2186      0      stevel 	}
   2187      0      stevel 
   2188      0      stevel 	if (p == NULL) {
   2189  11042        Erik 		if (!(ira->ira_flags & IRAF_IPSEC_SECURE)) {
   2190      0      stevel 			/*
   2191      0      stevel 			 * We have no policy; default to succeeding.
   2192      0      stevel 			 * XXX paranoid system design doesn't do this.
   2193      0      stevel 			 */
   2194   3448    dh155122 			BUMP_MIB(&ipst->ips_ip_mib, ipsecInSucceeded);
   2195  11042        Erik 			return (data_mp);
   2196      0      stevel 		} else {
   2197   3448    dh155122 			counter = DROPPER(ipss, ipds_spd_got_secure);
   2198   3192      danmcd 			ipsec_log_policy_failure(IPSEC_POLICY_NOT_NEEDED,
   2199   3448    dh155122 			    "ipsec_check_global_policy", ipha, ip6h, B_TRUE,
   2200   3448    dh155122 			    ns);
   2201      0      stevel 			goto fail;
   2202      0      stevel 		}
   2203      0      stevel 	}
   2204  11042        Erik 	if (ira->ira_flags & IRAF_IPSEC_SECURE) {
   2205  11042        Erik 		return (ipsec_check_ipsecin_policy(data_mp, p, ipha, ip6h,
   2206  11042        Erik 		    pkt_unique, ira, ns));
   2207   3192      danmcd 	}
   2208      0      stevel 	if (p->ipsp_act->ipa_allow_clear) {
   2209   3448    dh155122 		BUMP_MIB(&ipst->ips_ip_mib, ipsecInSucceeded);
   2210  11042        Erik 		IPPOL_REFRELE(p);
   2211  11042        Erik 		return (data_mp);
   2212  11042        Erik 	}
   2213  11042        Erik 	IPPOL_REFRELE(p);
   2214      0      stevel 	/*
   2215      0      stevel 	 * If we reach here, we will drop the packet because it failed the
   2216      0      stevel 	 * global policy check because the packet was cleartext, and it
   2217      0      stevel 	 * should not have been.
   2218      0      stevel 	 */
   2219   3192      danmcd 	ipsec_log_policy_failure(IPSEC_POLICY_MISMATCH,
   2220   3448    dh155122 	    "ipsec_check_global_policy", ipha, ip6h, B_FALSE, ns);
   2221   3448    dh155122 	counter = DROPPER(ipss, ipds_spd_got_clear);
   2222      0      stevel 
   2223      0      stevel fail:
   2224  11042        Erik 	ip_drop_packet(data_mp, B_TRUE, NULL, counter,
   2225   3448    dh155122 	    &ipss->ipsec_spd_dropper);
   2226   3448    dh155122 	BUMP_MIB(&ipst->ips_ip_mib, ipsecInFailed);
   2227      0      stevel 	return (NULL);
   2228      0      stevel }
   2229      0      stevel 
   2230      0      stevel /*
   2231      0      stevel  * We check whether an inbound datagram is a valid one
   2232      0      stevel  * to accept in clear. If it is secure, it is the job
   2233      0      stevel  * of IPSEC to log information appropriately if it
   2234      0      stevel  * suspects that it may not be the real one.
   2235      0      stevel  *
   2236      0      stevel  * It is called only while fanning out to the ULP
   2237      0      stevel  * where ULP accepts only secure data and the incoming
   2238      0      stevel  * is clear. Usually we never accept clear datagrams in
   2239      0      stevel  * such cases. ICMP is the only exception.
   2240      0      stevel  *
   2241      0      stevel  * NOTE : We don't call this function if the client (ULP)
   2242      0      stevel  * is willing to accept things in clear.
   2243      0      stevel  */
   2244      0      stevel boolean_t
   2245      0      stevel ipsec_inbound_accept_clear(mblk_t *mp, ipha_t *ipha, ip6_t *ip6h)
   2246      0      stevel {
   2247      0      stevel 	ushort_t iph_hdr_length;
   2248      0      stevel 	icmph_t *icmph;
   2249      0      stevel 	icmp6_t *icmp6;
   2250      0      stevel 	uint8_t *nexthdrp;
   2251      0      stevel 
   2252      0      stevel 	ASSERT((ipha != NULL && ip6h == NULL) ||
   2253      0      stevel 	    (ipha == NULL && ip6h != NULL));
   2254      0      stevel 
   2255      0      stevel 	if (ip6h != NULL) {
   2256      0      stevel 		iph_hdr_length = ip_hdr_length_v6(mp, ip6h);
   2257      0      stevel 		if (!ip_hdr_length_nexthdr_v6(mp, ip6h, &iph_hdr_length,
   2258      0      stevel 		    &nexthdrp)) {
   2259      0      stevel 			return (B_FALSE);
   2260      0      stevel 		}
   2261      0      stevel 		if (*nexthdrp != IPPROTO_ICMPV6)
   2262      0      stevel 			return (B_FALSE);
   2263      0      stevel 		icmp6 = (icmp6_t *)(&mp->b_rptr[iph_hdr_length]);
   2264      0      stevel 		/* Match IPv6 ICMP policy as closely as IPv4 as possible. */
   2265      0      stevel 		switch (icmp6->icmp6_type) {
   2266      0      stevel 		case ICMP6_PARAM_PROB:
   2267      0      stevel 			/* Corresponds to port/proto unreach in IPv4. */
   2268      0      stevel 		case ICMP6_ECHO_REQUEST:
   2269      0      stevel 			/* Just like IPv4. */
   2270      0      stevel 			return (B_FALSE);
   2271      0      stevel 
   2272      0      stevel 		case MLD_LISTENER_QUERY:
   2273      0      stevel 		case MLD_LISTENER_REPORT:
   2274      0      stevel 		case MLD_LISTENER_REDUCTION:
   2275      0      stevel 			/*
   2276      0      stevel 			 * XXX Seperate NDD in IPv4 what about here?
   2277      0      stevel 			 * Plus, mcast is important to ND.
   2278      0      stevel 			 */
   2279      0      stevel 		case ICMP6_DST_UNREACH:
   2280      0      stevel 			/* Corresponds to HOST/NET unreachable in IPv4. */
   2281      0      stevel 		case ICMP6_PACKET_TOO_BIG:
   2282      0      stevel 		case ICMP6_ECHO_REPLY:
   2283      0      stevel 			/* These are trusted in IPv4. */
   2284      0      stevel 		case ND_ROUTER_SOLICIT:
   2285      0      stevel 		case ND_ROUTER_ADVERT:
   2286      0      stevel 		case ND_NEIGHBOR_SOLICIT:
   2287      0      stevel 		case ND_NEIGHBOR_ADVERT:
   2288      0      stevel 		case ND_REDIRECT:
   2289      0      stevel 			/* Trust ND messages for now. */
   2290      0      stevel 		case ICMP6_TIME_EXCEEDED:
   2291      0      stevel 		default:
   2292      0      stevel 			return (B_TRUE);
   2293      0      stevel 		}
   2294      0      stevel 	} else {
   2295      0      stevel 		/*
   2296      0      stevel 		 * If it is not ICMP, fail this request.
   2297      0      stevel 		 */
   2298   3055      danmcd 		if (ipha->ipha_protocol != IPPROTO_ICMP) {
   2299   3055      danmcd #ifdef FRAGCACHE_DEBUG
   2300   3055      danmcd 			cmn_err(CE_WARN, "Dropping - ipha_proto = %d\n",
   2301   3055      danmcd 			    ipha->ipha_protocol);
   2302   3055      danmcd #endif
   2303   3055      danmcd 			return (B_FALSE);
   2304   3055      danmcd 		}
   2305      0      stevel 		iph_hdr_length = IPH_HDR_LENGTH(ipha);
   2306      0      stevel 		icmph = (icmph_t *)&mp->b_rptr[iph_hdr_length];
   2307      0      stevel 		/*
   2308      0      stevel 		 * It is an insecure icmp message. Check to see whether we are
   2309      0      stevel 		 * willing to accept this one.
   2310      0      stevel 		 */
   2311      0      stevel 
   2312      0      stevel 		switch (icmph->icmph_type) {
   2313      0      stevel 		case ICMP_ECHO_REPLY:
   2314      0      stevel 		case ICMP_TIME_STAMP_REPLY:
   2315      0      stevel 		case ICMP_INFO_REPLY:
   2316      0      stevel 		case ICMP_ROUTER_ADVERTISEMENT:
   2317      0      stevel 			/*
   2318      0      stevel 			 * We should not encourage clear replies if this
   2319      0      stevel 			 * client expects secure. If somebody is replying
   2320      0      stevel 			 * in clear some mailicious user watching both the
   2321      0      stevel 			 * request and reply, can do chosen-plain-text attacks.
   2322      0      stevel 			 * With global policy we might be just expecting secure
   2323      0      stevel 			 * but sending out clear. We don't know what the right
   2324      0      stevel 			 * thing is. We can't do much here as we can't control
   2325      0      stevel 			 * the sender here. Till we are sure of what to do,
   2326      0      stevel 			 * accept them.
   2327      0      stevel 			 */
   2328      0      stevel 			return (B_TRUE);
   2329      0      stevel 		case ICMP_ECHO_REQUEST:
   2330      0      stevel 		case ICMP_TIME_STAMP_REQUEST:
   2331      0      stevel 		case ICMP_INFO_REQUEST:
   2332      0      stevel 		case ICMP_ADDRESS_MASK_REQUEST:
   2333      0      stevel 		case ICMP_ROUTER_SOLICITATION:
   2334      0      stevel 		case ICMP_ADDRESS_MASK_REPLY:
   2335      0      stevel 			/*
   2336      0      stevel 			 * Don't accept this as somebody could be sending
   2337      0      stevel 			 * us plain text to get encrypted data. If we reply,
   2338      0      stevel 			 * it will lead to chosen plain text attack.
   2339      0      stevel 			 */
   2340      0      stevel 			return (B_FALSE);
   2341      0      stevel 		case ICMP_DEST_UNREACHABLE:
   2342      0      stevel 			switch (icmph->icmph_code) {
   2343      0      stevel 			case ICMP_FRAGMENTATION_NEEDED:
   2344      0      stevel 				/*
   2345      0      stevel 				 * Be in sync with icmp_inbound, where we have
   2346  11042        Erik 				 * already set dce_pmtu
   2347      0      stevel 				 */
   2348   3055      danmcd #ifdef FRAGCACHE_DEBUG
   2349   3055      danmcd 			cmn_err(CE_WARN, "ICMP frag needed\n");
   2350   3055      danmcd #endif
   2351      0      stevel 				return (B_TRUE);
   2352      0      stevel 			case ICMP_HOST_UNREACHABLE:
   2353      0      stevel 			case ICMP_NET_UNREACHABLE:
   2354      0      stevel 				/*
   2355      0      stevel 				 * By accepting, we could reset a connection.
   2356      0      stevel 				 * How do we solve the problem of some
   2357      0      stevel 				 * intermediate router sending in-secure ICMP
   2358      0      stevel 				 * messages ?
   2359      0      stevel 				 */
   2360      0      stevel 				return (B_TRUE);
   2361      0      stevel 			case ICMP_PORT_UNREACHABLE:
   2362      0      stevel 			case ICMP_PROTOCOL_UNREACHABLE:
   2363      0      stevel 			default :
   2364      0      stevel 				return (B_FALSE);
   2365      0      stevel 			}
   2366      0      stevel 		case ICMP_SOURCE_QUENCH:
   2367      0      stevel 			/*
   2368      0      stevel 			 * If this is an attack, TCP will slow start
   2369      0      stevel 			 * because of this. Is it very harmful ?
   2370      0      stevel 			 */
   2371      0      stevel 			return (B_TRUE);
   2372      0      stevel 		case ICMP_PARAM_PROBLEM:
   2373      0      stevel 			return (B_FALSE);
   2374      0      stevel 		case ICMP_TIME_EXCEEDED:
   2375      0      stevel 			return (B_TRUE);
   2376      0      stevel 		case ICMP_REDIRECT:
   2377      0      stevel 			return (B_FALSE);
   2378      0      stevel 		default :
   2379      0      stevel 			return (B_FALSE);
   2380      0      stevel 		}
   2381      0      stevel 	}
   2382      0      stevel }
   2383      0      stevel 
   2384      0      stevel void
   2385      0      stevel ipsec_latch_ids(ipsec_latch_t *ipl, ipsid_t *local, ipsid_t *remote)
   2386      0      stevel {
   2387      0      stevel 	mutex_enter(&ipl->ipl_lock);
   2388      0      stevel 
   2389      0      stevel 	if (ipl->ipl_ids_latched) {
   2390      0      stevel 		/* I lost, someone else got here before me */
   2391      0      stevel 		mutex_exit(&ipl->ipl_lock);
   2392      0      stevel 		return;
   2393      0      stevel 	}
   2394      0      stevel 
   2395      0      stevel 	if (local != NULL)
   2396      0      stevel 		IPSID_REFHOLD(local);
   2397      0      stevel 	if (remote != NULL)
   2398      0      stevel 		IPSID_REFHOLD(remote);
   2399      0      stevel 
   2400      0      stevel 	ipl->ipl_local_cid = local;
   2401      0      stevel 	ipl->ipl_remote_cid = remote;
   2402      0      stevel 	ipl->ipl_ids_latched = B_TRUE;
   2403      0      stevel 	mutex_exit(&ipl->ipl_lock);
   2404      0      stevel }
   2405      0      stevel 
   2406      0      stevel void
   2407  11042        Erik ipsec_latch_inbound(conn_t *connp, ip_recv_attr_t *ira)
   2408      0      stevel {
   2409      0      stevel 	ipsa_t *sa;
   2410  11042        Erik 	ipsec_latch_t *ipl = connp->conn_latch;
   2411      0      stevel 
   2412      0      stevel 	if (!ipl->ipl_ids_latched) {
   2413      0      stevel 		ipsid_t *local = NULL;
   2414      0      stevel 		ipsid_t *remote = NULL;
   2415      0      stevel 
   2416  11042        Erik 		if (!(ira->ira_flags & IRAF_LOOPBACK)) {
   2417  11042        Erik 			ASSERT(ira->ira_flags & IRAF_IPSEC_SECURE);
   2418  11042        Erik 			if (ira->ira_ipsec_esp_sa != NULL)
   2419  11042        Erik 				sa = ira->ira_ipsec_esp_sa;
   2420      0      stevel 			else
   2421  11042        Erik 				sa = ira->ira_ipsec_ah_sa;
   2422      0      stevel 			ASSERT(sa != NULL);
   2423      0      stevel 			local = sa->ipsa_dst_cid;
   2424      0      stevel 			remote = sa->ipsa_src_cid;
   2425      0      stevel 		}
   2426      0      stevel 		ipsec_latch_ids(ipl, local, remote);
   2427      0      stevel 	}
   2428  11042        Erik 	if (ira->ira_flags & IRAF_IPSEC_SECURE) {
   2429  11042        Erik 		if (connp->conn_latch_in_action != NULL) {
   2430  11042        Erik 			/*
   2431  11042        Erik 			 * Previously cached action.  This is probably
   2432  11042        Erik 			 * harmless, but in DEBUG kernels, check for
   2433  11042        Erik 			 * action equality.
   2434  11042        Erik 			 *
   2435  11042        Erik 			 * Preserve the existing action to preserve latch
   2436  11042        Erik 			 * invariance.
   2437  11042        Erik 			 */
   2438  11042        Erik 			ASSERT(connp->conn_latch_in_action ==
   2439  11042        Erik 			    ira->ira_ipsec_action);
   2440  11042        Erik 			return;
   2441  11042        Erik 		}
   2442  11042        Erik 		connp->conn_latch_in_action = ira->ira_ipsec_action;
   2443  11042        Erik 		IPACT_REFHOLD(connp->conn_latch_in_action);
   2444  11042        Erik 	}
   2445      0      stevel }
   2446      0      stevel 
   2447      0      stevel /*
   2448      0      stevel  * Check whether the policy constraints are met either for an
   2449      0      stevel  * inbound datagram; called from IP in numerous places.
   2450      0      stevel  *
   2451      0      stevel  * Note that this is not a chokepoint for inbound policy checks;
   2452    691    sommerfe  * see also ipsec_check_ipsecin_latch() and ipsec_check_global_policy()
   2453      0      stevel  */
   2454      0      stevel mblk_t *
   2455  11042        Erik ipsec_check_inbound_policy(mblk_t *mp, conn_t *connp,
   2456  11042        Erik     ipha_t *ipha, ip6_t *ip6h, ip_recv_attr_t *ira)
   2457  11042        Erik {
   2458  11042        Erik 	boolean_t	ret;
   2459  11042        Erik 	ipsec_latch_t	*ipl;
   2460  11042        Erik 	ipsec_action_t	*ap;
   2461  11042        Erik 	uint64_t	unique_id;
   2462   3448    dh155122 	ipsec_stack_t	*ipss;
   2463   3448    dh155122 	ip_stack_t	*ipst;
   2464   3448    dh155122 	netstack_t	*ns;
   2465   9953    Vladimir 	ipsec_policy_head_t *policy_head;
   2466  11042        Erik 	ipsec_policy_t	*p = NULL;
   2467      0      stevel 
   2468      0      stevel 	ASSERT(connp != NULL);
   2469   3448    dh155122 	ns = connp->conn_netstack;
   2470   3448    dh155122 	ipss = ns->netstack_ipsec;
   2471   3448    dh155122 	ipst = ns->netstack_ip;
   2472      0      stevel 
   2473  11042        Erik 	if (!(ira->ira_flags & IRAF_IPSEC_SECURE)) {
   2474      0      stevel 		/*
   2475      0      stevel 		 * This is the case where the incoming datagram is
   2476      0      stevel 		 * cleartext and we need to see whether this client
   2477      0      stevel 		 * would like to receive such untrustworthy things from
   2478      0      stevel 		 * the wire.
   2479      0      stevel 		 */
   2480      0      stevel 		ASSERT(mp != NULL);
   2481      0      stevel 
   2482   7443      George 		mutex_enter(&connp->conn_lock);
   2483   7443      George 		if (connp->conn_state_flags & CONN_CONDEMNED) {
   2484   7443      George 			mutex_exit(&connp->conn_lock);
   2485  11042        Erik 			ip_drop_packet(mp, B_TRUE, NULL,
   2486  11042        Erik 			    DROPPER(ipss, ipds_spd_got_clear),
   2487   7443      George 			    &ipss->ipsec_spd_dropper);
   2488   7443      George 			BUMP_MIB(&ipst->ips_ip_mib, ipsecInFailed);
   2489   7443      George 			return (NULL);
   2490   7443      George 		}
   2491  11042        Erik 		if (connp->conn_latch != NULL) {
   2492   7443      George 			/* Hold a reference in case the conn is closing */
   2493  11042        Erik 			p = connp->conn_latch_in_policy;
   2494  11042        Erik 			if (p != NULL)
   2495  11042        Erik 				IPPOL_REFHOLD(p);
   2496   7443      George 			mutex_exit(&connp->conn_lock);
   2497      0      stevel 			/*
   2498      0      stevel 			 * Policy is cached in the conn.
   2499      0      stevel 			 */
   2500  11042        Erik 			if (p != NULL && !p->ipsp_act->ipa_allow_clear) {
   2501      0      stevel 				ret = ipsec_inbound_accept_clear(mp,
   2502      0      stevel 				    ipha, ip6h);
   2503      0      stevel 				if (ret) {
   2504   3448    dh155122 					BUMP_MIB(&ipst->ips_ip_mib,
   2505   3448    dh155122 					    ipsecInSucceeded);
   2506  11042        Erik 					IPPOL_REFRELE(p);
   2507  11042        Erik 					return (mp);
   2508      0      stevel 				} else {
   2509      0      stevel 					ipsec_log_policy_failure(
   2510      0      stevel 					    IPSEC_POLICY_MISMATCH,
   2511      0      stevel 					    "ipsec_check_inbound_policy", ipha,
   2512   3448    dh155122 					    ip6h, B_FALSE, ns);
   2513  11042        Erik 					ip_drop_packet(mp, B_TRUE, NULL,
   2514   3448    dh155122 					    DROPPER(ipss, ipds_spd_got_clear),
   2515   3448    dh155122 					    &ipss->ipsec_spd_dropper);
   2516   3448    dh155122 					BUMP_MIB(&ipst->ips_ip_mib,
   2517   3448    dh155122 					    ipsecInFailed);
   2518  11042        Erik 					IPPOL_REFRELE(p);
   2519      0      stevel 					return (NULL);
   2520      0      stevel 				}
   2521      0      stevel 			} else {
   2522   3448    dh155122 				BUMP_MIB(&ipst->ips_ip_mib, ipsecInSucceeded);
   2523  11042        Erik 				if (p != NULL)
   2524  11042        Erik 					IPPOL_REFRELE(p);
   2525  11042        Erik 				return (mp);
   2526  11042        Erik 			}
   2527  11042        Erik 		} else {
   2528   9953    Vladimir 			policy_head = connp->conn_policy;
   2529   9953    Vladimir 
   2530   9953    Vladimir 			/* Hold a reference in case the conn is closing */
   2531   9953    Vladimir 			if (policy_head != NULL)
   2532   9953    Vladimir 				IPPH_REFHOLD(policy_head);
   2533   7443      George 			mutex_exit(&connp->conn_lock);
   2534      0      stevel 			/*
   2535      0      stevel 			 * As this is a non-hardbound connection we need
   2536      0      stevel 			 * to look at both per-socket policy and global
   2537  11042        Erik 			 * policy.
   2538  11042        Erik 			 */
   2539  11042        Erik 			mp = ipsec_check_global_policy(mp, connp,
   2540  11042        Erik 			    ipha, ip6h, ira, ns);
   2541   9953    Vladimir 			if (policy_head != NULL)
   2542   9953    Vladimir 				IPPH_REFRELE(policy_head, ns);
   2543  11042        Erik 			return (mp);
   2544  11042        Erik 		}
   2545  11042        Erik 	}
   2546      0      stevel 
   2547   7443      George 	mutex_enter(&connp->conn_lock);
   2548   7443      George 	/* Connection is closing */
   2549   7443      George 	if (connp->conn_state_flags & CONN_CONDEMNED) {
   2550   7443      George 		mutex_exit(&connp->conn_lock);
   2551  11042        Erik 		ip_drop_packet(mp, B_TRUE, NULL,
   2552  11042        Erik 		    DROPPER(ipss, ipds_spd_got_clear),
   2553   7443      George 		    &ipss->ipsec_spd_dropper);
   2554   7443      George 		BUMP_MIB(&ipst->ips_ip_mib, ipsecInFailed);
   2555   7443      George 		return (NULL);
   2556   7443      George 	}
   2557   7443      George 
   2558   7443      George 	/*
   2559   7443      George 	 * Once a connection is latched it remains so for life, the conn_latch
   2560   7443      George 	 * pointer on the conn has not changed, simply initializing ipl here
   2561   7443      George 	 * as the earlier initialization was done only in the cleartext case.
   2562   7443      George 	 */
   2563   7456      danmcd 	if ((ipl = connp->conn_latch) == NULL) {
   2564   9953    Vladimir 		mblk_t *retmp;
   2565   9953    Vladimir 		policy_head = connp->conn_policy;
   2566   9953    Vladimir 
   2567   9953    Vladimir 		/* Hold a reference in case the conn is closing */
   2568   9953    Vladimir 		if (policy_head != NULL)
   2569   9953    Vladimir 			IPPH_REFHOLD(policy_head);
   2570   7443      George 		mutex_exit(&connp->conn_lock);
   2571      0      stevel 		/*
   2572    691    sommerfe 		 * We don't have policies cached in the conn
   2573      0      stevel 		 * for this stream. So, look at the global
   2574      0      stevel 		 * policy. It will check against conn or global
   2575      0      stevel 		 * depending on whichever is stronger.
   2576      0      stevel 		 */
   2577  11042        Erik 		retmp = ipsec_check_global_policy(mp, connp,
   2578  11042        Erik 		    ipha, ip6h, ira, ns);
   2579   9953    Vladimir 		if (policy_head != NULL)
   2580   9953    Vladimir 			IPPH_REFRELE(policy_head, ns);
   2581   9953    Vladimir 		return (retmp);
   2582    691    sommerfe 	}
   2583    691    sommerfe 
   2584   7443      George 	IPLATCH_REFHOLD(ipl);
   2585  11042        Erik 	/* Hold reference on conn_latch_in_action in case conn is closing */
   2586  11042        Erik 	ap = connp->conn_latch_in_action;
   2587  11042        Erik 	if (ap != NULL)
   2588  11042        Erik 		IPACT_REFHOLD(ap);
   2589   7443      George 	mutex_exit(&connp->conn_lock);
   2590   7443      George 
   2591  11042        Erik 	if (ap != NULL) {
   2592      0      stevel 		/* Policy is cached & latched; fast(er) path */
   2593      0      stevel 		const char *reason;
   2594      0      stevel 		kstat_named_t *counter;
   2595   3448    dh155122 
   2596  11042        Erik 		if (ipsec_check_ipsecin_latch(ira, mp, ipl, ap,
   2597  11042        Erik 		    ipha, ip6h, &reason, &counter, connp, ns)) {
   2598   3448    dh155122 			BUMP_MIB(&ipst->ips_ip_mib, ipsecInSucceeded);
   2599  11042        Erik 			IPLATCH_REFRELE(ipl);
   2600  11042        Erik 			IPACT_REFRELE(ap);
   2601  11042        Erik 			return (mp);
   2602      0      stevel 		}
   2603   3448    dh155122 		ipsec_rl_strlog(ns, IP_MOD_ID, 0, 0,
   2604   3448    dh155122 		    SL_ERROR|SL_WARN|SL_CONSOLE,
   2605      0      stevel 		    "ipsec inbound policy mismatch: %s, packet dropped\n",
   2606      0      stevel 		    reason);
   2607  11042        Erik 		ip_drop_packet(mp, B_TRUE, NULL, counter,
   2608   3448    dh155122 		    &ipss->ipsec_spd_dropper);
   2609   3448    dh155122 		BUMP_MIB(&ipst->ips_ip_mib, ipsecInFailed);
   2610  11042        Erik 		IPLATCH_REFRELE(ipl);
   2611  11042        Erik 		IPACT_REFRELE(ap);
   2612  11042        Erik 		return (NULL);
   2613  11042        Erik 	}
   2614  11042        Erik 	if ((p = connp->conn_latch_in_policy) == NULL) {
   2615    691    sommerfe 		ipsec_weird_null_inbound_policy++;
   2616  11042        Erik 		IPLATCH_REFRELE(ipl);
   2617  11042        Erik 		return (mp);
   2618    691    sommerfe 	}
   2619      0      stevel 
   2620   3055      danmcd 	unique_id = conn_to_unique(connp, mp, ipha, ip6h);
   2621  11042        Erik 	IPPOL_REFHOLD(p);
   2622  11042        Erik 	mp = ipsec_check_ipsecin_policy(mp, p, ipha, ip6h, unique_id, ira, ns);
   2623      0      stevel 	/*
   2624      0      stevel 	 * NOTE: ipsecIn{Failed,Succeeeded} bumped by
   2625      0      stevel 	 * ipsec_check_ipsecin_policy().
   2626      0      stevel 	 */
   2627  11042        Erik 	if (mp != NULL)
   2628  11042        Erik 		ipsec_latch_inbound(connp, ira);
   2629  11042        Erik 	IPLATCH_REFRELE(ipl);
   2630  11042        Erik 	return (mp);
   2631  11042        Erik }
   2632  11042        Erik 
   2633  11042        Erik /*
   2634  11042        Erik  * Handle all sorts of cases like tunnel-mode and ICMP.
   2635  10934  sommerfeld  */
   2636  10934  sommerfeld static int
   2637  10934  sommerfeld prepended_length(mblk_t *mp, uintptr_t hptr)
   2638  10934  sommerfeld {
   2639  10934  sommerfeld 	int rc = 0;
   2640  10934  sommerfeld 
   2641  10934  sommerfeld 	while (mp != NULL) {
   2642  10934  sommerfeld 		if (hptr >= (uintptr_t)mp->b_rptr && hptr <
   2643  10934  sommerfeld 		    (uintptr_t)mp->b_wptr) {
   2644  10934  sommerfeld 			rc += (int)(hptr - (uintptr_t)mp->b_rptr);
   2645  10934  sommerfeld 			break;	/* out of while loop */
   2646  10934  sommerfeld 		}
   2647  10934  sommerfeld 		rc += (int)MBLKL(mp);
   2648  10934  sommerfeld 		mp = mp->b_cont;
   2649  10934  sommerfeld 	}
   2650  10934  sommerfeld 
   2651  10934  sommerfeld 	if (mp == NULL) {
   2652  10934  sommerfeld 		/*
   2653  10934  sommerfeld 		 * IF (big IF) we make it here by naturally exiting the loop,
   2654  10934  sommerfeld 		 * then ip6h isn't in the mblk chain "mp" at all.
   2655  10934  sommerfeld 		 *
   2656  10934  sommerfeld 		 * The only case where this happens is with a reversed IP
   2657  10934  sommerfeld 		 * header that gets passed up by inbound ICMP processing.
   2658  10934  sommerfeld 		 * This unfortunately triggers longstanding bug 6478464.  For
   2659  10934  sommerfeld 		 * now, just pass up 0 for the answer.
   2660  10934  sommerfeld 		 */
   2661  10934  sommerfeld #ifdef DEBUG_NOT_UNTIL_6478464
   2662  10934  sommerfeld 		ASSERT(mp != NULL);
   2663  10934  sommerfeld #endif
   2664  10934  sommerfeld 		rc = 0;
   2665  10934  sommerfeld 	}
   2666  10934  sommerfeld 
   2667  10934  sommerfeld 	return (rc);
   2668  10934  sommerfeld }
   2669  10934  sommerfeld 
   2670  10934  sommerfeld /*
   2671   3055      danmcd  * Returns:
   2672   3055      danmcd  *
   2673   3055      danmcd  * SELRET_NOMEM --> msgpullup() needed to gather things failed.
   2674   3055      danmcd  * SELRET_BADPKT --> If we're being called after tunnel-mode fragment
   2675   3055      danmcd  *		     gathering, the initial fragment is too short for
   2676   3055      danmcd  *		     useful data.  Only returned if SEL_TUNNEL_FIRSTFRAG is
   2677   3055      danmcd  *		     set.
   2678   3055      danmcd  * SELRET_SUCCESS --> "sel" now has initialized IPsec selector data.
   2679   3055      danmcd  * SELRET_TUNFRAG --> This is a fragment in a tunnel-mode packet.  Caller
   2680   3055      danmcd  *		      should put this packet in a fragment-gathering queue.
   2681   3055      danmcd  *		      Only returned if SEL_TUNNEL_MODE and SEL_PORT_POLICY
   2682   3055      danmcd  *		      is set.
   2683  11042        Erik  *
   2684  11042        Erik  * Note that ipha/ip6h can be in a different mblk (mp->b_cont) in the case
   2685  11042        Erik  * of tunneled packets.
   2686  11042        Erik  * Also, mp->b_rptr can be an ICMP error where ipha/ip6h is the packet in
   2687  11042        Erik  * error past the ICMP error.
   2688   3055      danmcd  */
   2689   3055      danmcd static selret_t
   2690   3055      danmcd ipsec_init_inbound_sel(ipsec_selector_t *sel, mblk_t *mp, ipha_t *ipha,
   2691   3055      danmcd     ip6_t *ip6h, uint8_t sel_flags)
   2692   3055      danmcd {
   2693   3055      danmcd 	uint16_t *ports;
   2694  11042        Erik 	int outer_hdr_len = 0;	/* For ICMP or tunnel-mode cases... */
   2695   3055      danmcd 	ushort_t hdr_len;
   2696   3055      danmcd 	mblk_t *spare_mp = NULL;
   2697  10934  sommerfeld 	uint8_t *nexthdrp, *transportp;
   2698   3055      danmcd 	uint8_t nexthdr;
   2699  10934  sommerfeld 	uint8_t icmp_proto;
   2700  11042        Erik 	ip_pkt_t ipp;
   2701   3055      danmcd 	boolean_t port_policy_present = (sel_flags & SEL_PORT_POLICY);
   2702   3055      danmcd 	boolean_t is_icmp = (sel_flags & SEL_IS_ICMP);
   2703   3055      danmcd 	boolean_t tunnel_mode = (sel_flags & SEL_TUNNEL_MODE);
   2704  10616   Sebastien 	boolean_t post_frag = (sel_flags & SEL_POST_FRAG);
   2705   3055      danmcd 
   2706   3055      danmcd 	ASSERT((ipha == NULL && ip6h != NULL) ||
   2707   3055      danmcd 	    (ipha != NULL && ip6h == NULL));
   2708   3055      danmcd 
   2709   3055      danmcd 	if (ip6h != NULL) {
   2710  10934  sommerfeld 		outer_hdr_len = prepended_length(mp, (uintptr_t)ip6h);
   2711  10934  sommerfeld 		nexthdr = ip6h->ip6_nxt;
   2712  10934  sommerfeld 		icmp_proto = IPPROTO_ICMPV6;
   2713   3055      danmcd 		sel->ips_isv4 = B_FALSE;
   2714   3055      danmcd 		sel->ips_local_addr_v6 = ip6h->ip6_dst;
   2715   3055      danmcd 		sel->ips_remote_addr_v6 = ip6h->ip6_src;
   2716   3055      danmcd 
   2717   3055      danmcd 		bzero(&ipp, sizeof (ipp));
   2718  11042        Erik 		(void) ip_find_hdr_v6(mp, ip6h, B_FALSE, &ipp, NULL);
   2719   3055      danmcd 
   2720   3055      danmcd 		switch (nexthdr) {
   2721   3055      danmcd 		case IPPROTO_HOPOPTS:
   2722   3055      danmcd 		case IPPROTO_ROUTING:
   2723   3055      danmcd 		case IPPROTO_DSTOPTS:
   2724   3055      danmcd 		case IPPROTO_FRAGMENT:
   2725   3055      danmcd 			/*
   2726   3055      danmcd 			 * Use ip_hdr_length_nexthdr_v6().  And have a spare
   2727   3055      danmcd 			 * mblk that's contiguous to feed it
   2728   3055      danmcd 			 */
   2729   3055      danmcd 			if ((spare_mp = msgpullup(mp, -1)) == NULL)
   2730   3055      danmcd 				return (SELRET_NOMEM);
   2731   3055      danmcd 			if (!ip_hdr_length_nexthdr_v6(spare_mp,
   2732   3055      danmcd 			    (ip6_t *)(spare_mp->b_rptr + outer_hdr_len),
   2733   5245      danmcd 			    &hdr_len, &nexthdrp)) {
   2734   3055      danmcd 				/* Malformed packet - caller frees. */
   2735   3055      danmcd 				ipsec_freemsg_chain(spare_mp);
   2736   3055      danmcd 				return (SELRET_BADPKT);
   2737   3055      danmcd 			}
   2738   3055      danmcd 			nexthdr = *nexthdrp;
   2739   3055      danmcd 			/* We can just extract based on hdr_len now. */
   2740   3055      danmcd 			break;
   2741   3055      danmcd 		default:
   2742   3055      danmcd 			hdr_len = IPV6_HDR_LEN;
   2743   3055      danmcd 			break;
   2744   3055      danmcd 		}
   2745   3055      danmcd 
   2746   3055      danmcd 		if (port_policy_present && IS_V6_FRAGMENT(ipp) && !is_icmp) {
   2747   3055      danmcd 			/* IPv6 Fragment */
   2748   3055      danmcd 			ipsec_freemsg_chain(spare_mp);
   2749   3055      danmcd 			return (SELRET_TUNFRAG);
   2750   3055      danmcd 		}
   2751  10934  sommerfeld 		transportp = (uint8_t *)ip6h + hdr_len;
   2752  10934  sommerfeld 	} else {
   2753  10934  sommerfeld 		outer_hdr_len = prepended_length(mp, (uintptr_t)ipha);
   2754  10934  sommerfeld 		icmp_proto = IPPROTO_ICMP;
   2755   3055      danmcd 		sel->ips_isv4 = B_TRUE;
   2756   3055      danmcd 		sel->ips_local_addr_v4 = ipha->ipha_dst;
   2757   3055      danmcd 		sel->ips_remote_addr_v4 = ipha->ipha_src;
   2758   3055      danmcd 		nexthdr = ipha->ipha_protocol;
   2759   3055      danmcd 		hdr_len = IPH_HDR_LENGTH(ipha);
   2760   3055      danmcd 
   2761   3055      danmcd 		if (port_policy_present &&
   2762   3055      danmcd 		    IS_V4_FRAGMENT(ipha->ipha_fragment_offset_and_flags) &&
   2763   3055      danmcd 		    !is_icmp) {
   2764   3055      danmcd 			/* IPv4 Fragment */
   2765   3055      danmcd 			ipsec_freemsg_chain(spare_mp);
   2766   3055      danmcd 			return (SELRET_TUNFRAG);
   2767   3055      danmcd 		}
   2768  10934  sommerfeld 		transportp = (uint8_t *)ipha + hdr_len;
   2769   3055      danmcd 	}
   2770   3055      danmcd 	sel->ips_protocol = nexthdr;
   2771   3055      danmcd 
   2772   3055      danmcd 	if ((nexthdr != IPPROTO_TCP && nexthdr != IPPROTO_UDP &&
   2773  10934  sommerfeld 	    nexthdr != IPPROTO_SCTP && nexthdr != icmp_proto) ||
   2774  10616   Sebastien 	    (!port_policy_present && !post_frag && tunnel_mode)) {
   2775   3055      danmcd 		sel->ips_remote_port = sel->ips_local_port = 0;
   2776   3055      danmcd 		ipsec_freemsg_chain(spare_mp);
   2777   3055      danmcd 		return (SELRET_SUCCESS);
   2778   3055      danmcd 	}
   2779   3055      danmcd 
   2780  10934  sommerfeld 	if (transportp + 4 > mp->b_wptr) {
   2781   3055      danmcd 		/* If we didn't pullup a copy already, do so now. */
   2782   3055      danmcd 		/*
   2783   3055      danmcd 		 * XXX performance, will upper-layers frequently split TCP/UDP
   2784   3055      danmcd 		 * apart from IP or options?  If so, perhaps we should revisit
   2785   3055      danmcd 		 * the spare_mp strategy.
   2786   3055      danmcd 		 */
   2787   3055      danmcd 		ipsec_hdr_pullup_needed++;
   2788   3055      danmcd 		if (spare_mp == NULL &&
   2789   3055      danmcd 		    (spare_mp = msgpullup(mp, -1)) == NULL) {
   2790   3055      danmcd 			return (SELRET_NOMEM);
   2791   3055      danmcd 		}
   2792  10934  sommerfeld 		transportp = &spare_mp->b_rptr[hdr_len + outer_hdr_len];
   2793  10934  sommerfeld 	}
   2794  10934  sommerfeld 
   2795  10934  sommerfeld 	if (nexthdr == icmp_proto) {
   2796  10934  sommerfeld 		sel->ips_icmp_type = *transportp++;
   2797  10934  sommerfeld 		sel->ips_icmp_code = *transportp;
   2798   3055      danmcd 		sel->ips_remote_port = sel->ips_local_port = 0;
   2799   3055      danmcd 	} else {
   2800  10934  sommerfeld 		ports = (uint16_t *)transportp;
   2801   3055      danmcd 		sel->ips_remote_port = *ports++;
   2802   3055      danmcd 		sel->ips_local_port = *ports;
   2803   3055      danmcd 	}
   2804   3055      danmcd 	ipsec_freemsg_chain(spare_mp);
   2805   3055      danmcd 	return (SELRET_SUCCESS);
   2806   3055      danmcd }
   2807   3055      danmcd 
   2808  11042        Erik /*
   2809  11042        Erik  * This is called with a b_next chain of messages from the fragcache code,
   2810  11042        Erik  * hence it needs to discard a chain on error.
   2811  11042        Erik  */
   2812   3055      danmcd static boolean_t
   2813   3055      danmcd ipsec_init_outbound_ports(ipsec_selector_t *sel, mblk_t *mp, ipha_t *ipha,
   2814   3448    dh155122     ip6_t *ip6h, int outer_hdr_len, ipsec_stack_t *ipss)
   2815   3055      danmcd {
   2816   3055      danmcd 	/*
   2817   3055      danmcd 	 * XXX cut&paste shared with ipsec_init_inbound_sel
   2818   3055      danmcd 	 */
   2819      0      stevel 	uint16_t *ports;
   2820      0      stevel 	ushort_t hdr_len;
   2821      0      stevel 	mblk_t *spare_mp = NULL;
   2822      0      stevel 	uint8_t *nexthdrp;
   2823      0      stevel 	uint8_t nexthdr;
   2824      0      stevel 	uint8_t *typecode;
   2825      0      stevel 	uint8_t check_proto;
   2826      0      stevel 
   2827      0      stevel 	ASSERT((ipha == NULL && ip6h != NULL) ||
   2828      0      stevel 	    (ipha != NULL && ip6h == NULL));
   2829      0      stevel 
   2830      0      stevel 	if (ip6h != NULL) {
   2831      0      stevel 		check_proto = IPPROTO_ICMPV6;
   2832      0      stevel 		nexthdr = ip6h->ip6_nxt;
   2833      0      stevel 		switch (nexthdr) {
   2834      0      stevel 		case IPPROTO_HOPOPTS:
   2835      0      stevel 		case IPPROTO_ROUTING:
   2836      0      stevel 		case IPPROTO_DSTOPTS:
   2837   3055      danmcd 		case IPPROTO_FRAGMENT:
   2838      0      stevel 			/*
   2839      0      stevel 			 * Use ip_hdr_length_nexthdr_v6().  And have a spare
   2840      0      stevel 			 * mblk that's contiguous to feed it
   2841      0      stevel 			 */
   2842   3055      danmcd 			spare_mp = msgpullup(mp, -1);
   2843   3055      danmcd 			if (spare_mp == NULL ||
   2844   3055      danmcd 			    !ip_hdr_length_nexthdr_v6(spare_mp,
   2845   5245      danmcd 			    (ip6_t *)(spare_mp->b_rptr + outer_hdr_len),
   2846   5245      danmcd 			    &hdr_len, &nexthdrp)) {
   2847   3055      danmcd 				/* Always works, even if NULL. */
   2848   3055      danmcd 				ipsec_freemsg_chain(spare_mp);
   2849  11042        Erik 				ip_drop_packet_chain(mp, B_FALSE, NULL,
   2850   3448    dh155122 				    DROPPER(ipss, ipds_spd_nomem),
   2851   3448    dh155122 				    &ipss->ipsec_spd_dropper);
   2852   3055      danmcd 				return (B_FALSE);
   2853   3055      danmcd 			} else {
   2854   3055      danmcd 				nexthdr = *nexthdrp;
   2855   3055      danmcd 				/* We can just extract based on hdr_len now. */
   2856   3055      danmcd 			}
   2857      0      stevel 			break;
   2858      0      stevel 		default:
   2859      0      stevel 			hdr_len = IPV6_HDR_LEN;
   2860      0      stevel 			break;
   2861      0      stevel 		}
   2862      0      stevel 	} else {
   2863      2     pwernau 		check_proto = IPPROTO_ICMP;
   2864   3055      danmcd 		hdr_len = IPH_HDR_LENGTH(ipha);
   2865      0      stevel 		nexthdr = ipha->ipha_protocol;
   2866   3055      danmcd 	}
   2867   3055      danmcd 
   2868      0      stevel 	sel->ips_protocol = nexthdr;
   2869      0      stevel 	if (nexthdr != IPPROTO_TCP && nexthdr != IPPROTO_UDP &&
   2870      0      stevel 	    nexthdr != IPPROTO_SCTP && nexthdr != check_proto) {
   2871   3055      danmcd 		sel->ips_local_port = sel->ips_remote_port = 0;
   2872   3055      danmcd 		ipsec_freemsg_chain(spare_mp); /* Always works, even if NULL */
   2873      0      stevel 		return (B_TRUE);
   2874      0      stevel 	}
   2875      0      stevel 
   2876   3055      danmcd 	if (&mp->b_rptr[hdr_len] + 4 + outer_hdr_len > mp->b_wptr) {
   2877      0      stevel 		/* If we didn't pullup a copy already, do so now. */
   2878      0      stevel 		/*
   2879      0      stevel 		 * XXX performance, will upper-layers frequently split TCP/UDP
   2880      0      stevel 		 * apart from IP or options?  If so, perhaps we should revisit
   2881      0      stevel 		 * the spare_mp strategy.
   2882   3055      danmcd 		 *
   2883   3055      danmcd 		 * XXX should this be msgpullup(mp, hdr_len+4) ???
   2884   3055      danmcd 		 */
   2885      0      stevel 		if (spare_mp == NULL &&
   2886      0      stevel 		    (spare_mp = msgpullup(mp, -1)) == NULL) {
   2887  11042        Erik 			ip_drop_packet_chain(mp, B_FALSE, NULL,
   2888   3448    dh155122 			    DROPPER(ipss, ipds_spd_nomem),
   2889   3448    dh155122 			    &ipss->ipsec_spd_dropper);
   2890   3055      danmcd 			return (B_FALSE);
   2891   3055      danmcd 		}
   2892   3055      danmcd 		ports = (uint16_t *)&spare_mp->b_rptr[hdr_len + outer_hdr_len];
   2893   3055      danmcd 	} else {
   2894   3055      danmcd 		ports = (uint16_t *)&mp->b_rptr[hdr_len + outer_hdr_len];
   2895      0      stevel 	}
   2896      0      stevel 
   2897      0      stevel 	if (nexthdr == check_proto) {
   2898      0      stevel 		typecode = (uint8_t *)ports;
   2899      0      stevel 		sel->ips_icmp_type = *typecode++;
   2900      0      stevel 		sel->ips_icmp_code = *typecode;
   2901      0      stevel 		sel->ips_remote_port = sel->ips_local_port = 0;
   2902   3055      danmcd 	} else {
   2903   3055      danmcd 		sel->ips_local_port = *ports++;
   2904   3055      danmcd 		sel->ips_remote_port = *ports;
   2905   3055      danmcd 	}
   2906   3055      danmcd 	ipsec_freemsg_chain(spare_mp);	/* Always works, even if NULL */
   2907      0      stevel 	return (B_TRUE);
   2908      0      stevel }
   2909      0      stevel 
   2910      0      stevel /*
   2911  11042        Erik  * Prepend an mblk with a ipsec_crypto_t to the message chain.
   2912  11042        Erik  * Frees the argument and returns NULL should the allocation fail.
   2913  11042        Erik  * Returns the pointer to the crypto data part.
   2914  11042        Erik  */
   2915  11042        Erik mblk_t *
   2916  11042        Erik ipsec_add_crypto_data(mblk_t *data_mp, ipsec_crypto_t **icp)
   2917  11042        Erik {
   2918  11042        Erik 	mblk_t	*mp;
   2919  11042        Erik 
   2920  11042        Erik 	mp = allocb(sizeof (ipsec_crypto_t), BPRI_MED);
   2921  11042        Erik 	if (mp == NULL) {
   2922  11042        Erik 		freemsg(data_mp);
   2923  11042        Erik 		return (NULL);
   2924  11042        Erik 	}
   2925  11042        Erik 	bzero(mp->b_rptr, sizeof (ipsec_crypto_t));
   2926  11042        Erik 	mp->b_wptr += sizeof (ipsec_crypto_t);
   2927  11042        Erik 	mp->b_cont = data_mp;
   2928  11042        Erik 	mp->b_datap->db_type = M_EVENT;	/* For ASSERT */
   2929  11042        Erik 	*icp = (ipsec_crypto_t *)mp->b_rptr;
   2930  11042        Erik 	return (mp);
   2931  11042        Erik }
   2932  11042        Erik 
   2933  11042        Erik /*
   2934  11042        Erik  * Remove what was prepended above. Return b_cont and a pointer to the
   2935  11042        Erik  * crypto data.
   2936  11042        Erik  * The caller must call ipsec_free_crypto_data for mblk once it is done
   2937  11042        Erik  * with the crypto data.
   2938  11042        Erik  */
   2939  11042        Erik mblk_t *
   2940  11042        Erik ipsec_remove_crypto_data(mblk_t *crypto_mp, ipsec_crypto_t **icp)
   2941  11042        Erik {
   2942  11042        Erik 	ASSERT(crypto_mp->b_datap->db_type == M_EVENT);
   2943  11042        Erik 	ASSERT(MBLKL(crypto_mp) == sizeof (ipsec_crypto_t));
   2944  11042        Erik 
   2945  11042        Erik 	*icp = (ipsec_crypto_t *)crypto_mp->b_rptr;
   2946  11042        Erik 	return (crypto_mp->b_cont);
   2947  11042        Erik }
   2948  11042        Erik 
   2949  11042        Erik /*
   2950  11042        Erik  * Free what was prepended above. Return b_cont.
   2951  11042        Erik  */
   2952  11042        Erik mblk_t *
   2953  11042        Erik ipsec_free_crypto_data(mblk_t *crypto_mp)
   2954  11042        Erik {
   2955  11042        Erik 	mblk_t	*mp;
   2956  11042        Erik 
   2957  11042        Erik 	ASSERT(crypto_mp->b_datap->db_type == M_EVENT);
   2958  11042        Erik 	ASSERT(MBLKL(crypto_mp) == sizeof (ipsec_crypto_t));
   2959  11042        Erik 
   2960  11042        Erik 	mp = crypto_mp->b_cont;
   2961  11042        Erik 	freeb(crypto_mp);
   2962  11042        Erik 	return (mp);
   2963  11042        Erik }
   2964  11042        Erik 
   2965  11042        Erik /*
   2966      0      stevel  * Create an ipsec_action_t based on the way an inbound packet was protected.
   2967      0      stevel  * Used to reflect traffic back to a sender.
   2968      0      stevel  *
   2969      0      stevel  * We don't bother interning the action into the hash table.
   2970      0      stevel  */
   2971      0      stevel ipsec_action_t *
   2972  11042        Erik ipsec_in_to_out_action(ip_recv_attr_t *ira)
   2973      0      stevel {
   2974      0      stevel 	ipsa_t *ah_assoc, *esp_assoc;
   2975      0      stevel 	uint_t auth_alg = 0, encr_alg = 0, espa_alg = 0;
   2976      0      stevel 	ipsec_action_t *ap;
   2977      0      stevel 	boolean_t unique;
   2978      0      stevel 
   2979      0      stevel 	ap = kmem_cache_alloc(ipsec_action_cache, KM_NOSLEEP);
   2980      0      stevel 
   2981      0      stevel 	if (ap == NULL)
   2982      0      stevel 		return (NULL);
   2983      0      stevel 
   2984      0      stevel 	bzero(ap, sizeof (*ap));
   2985     81    sommerfe 	HASH_NULL(ap, ipa_hash);
   2986      0      stevel 	ap->ipa_next = NULL;
   2987      0      stevel 	ap->ipa_refs = 1;
   2988      0      stevel 
   2989      0      stevel 	/*
   2990      0      stevel 	 * Get the algorithms that were used for this packet.
   2991      0      stevel 	 */
   2992      0      stevel 	ap->ipa_act.ipa_type = IPSEC_ACT_APPLY;
   2993      0      stevel 	ap->ipa_act.ipa_log = 0;
   2994  11042        Erik 	ASSERT(ira->ira_flags & IRAF_IPSEC_SECURE);
   2995  11042        Erik 
   2996  11042        Erik 	ah_assoc = ira->ira_ipsec_ah_sa;
   2997      0      stevel 	ap->ipa_act.ipa_apply.ipp_use_ah = (ah_assoc != NULL);
   2998      0      stevel 
   2999  11042        Erik 	esp_assoc = ira->ira_ipsec_esp_sa;
   3000      0      stevel 	ap->ipa_act.ipa_apply.ipp_use_esp = (esp_assoc != NULL);
   3001      0      stevel 
   3002      0      stevel 	if (esp_assoc != NULL) {
   3003      0      stevel 		encr_alg = esp_assoc->ipsa_encr_alg;
   3004      0      stevel 		espa_alg = esp_assoc->ipsa_auth_alg;
   3005      0      stevel 		ap->ipa_act.ipa_apply.ipp_use_espa = (espa_alg != 0);
   3006      0      stevel 	}
   3007      0      stevel 	if (ah_assoc != NULL)
   3008      0      stevel 		auth_alg = ah_assoc->ipsa_auth_alg;
   3009      0      stevel 
   3010      0      stevel 	ap->ipa_act.ipa_apply.ipp_encr_alg = (uint8_t)encr_alg;
   3011      0      stevel 	ap->ipa_act.ipa_apply.ipp_auth_alg = (uint8_t)auth_alg;
   3012      0      stevel 	ap->ipa_act.ipa_apply.ipp_esp_auth_alg = (uint8_t)espa_alg;
   3013  11042        Erik 	ap->ipa_act.ipa_apply.ipp_use_se =
   3014  11042        Erik 	    !!(ira->ira_flags & IRAF_IPSEC_DECAPS);
   3015      0      stevel 	unique = B_FALSE;
   3016      0      stevel 
   3017      0      stevel 	if (esp_assoc != NULL) {
   3018      0      stevel 		ap->ipa_act.ipa_apply.ipp_espa_minbits =
   3019      0      stevel 		    esp_assoc->