4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <sys/types.h>
27 #include <sys/stream.h>
28 #include <sys/strsubr.h>
29 #include <sys/sunddi.h>
31 #include <sys/strlog.h>
33 #include <inet/common.h>
34 #include <inet/mib2.h>
38 #include <net/pfkeyv2.h>
39 #include <inet/sadb.h>
40 #include <inet/ipsec_impl.h>
41 #include <inet/ipdrop.h>
42 #include <inet/ipsecesp.h>
43 #include <inet/ipsecah.h>
44 #include <sys/kstat.h>
47 * Returns B_TRUE if the identities in the SA match the identities
48 * in the "latch" structure.
52 ipsec_match_outbound_ids(ipsec_latch_t
*ipl
, ipsa_t
*sa
)
54 ASSERT(ipl
->ipl_ids_latched
== B_TRUE
);
55 return ipsid_equal(ipl
->ipl_local_cid
, sa
->ipsa_src_cid
) &&
56 ipsid_equal(ipl
->ipl_remote_cid
, sa
->ipsa_dst_cid
);
60 * Look up a security association based on the unique ID generated by IP and
61 * transport or tunnel information, such as ports and upper-layer protocol,
62 * and the inner and outer address(es). Used for uniqueness testing and
63 * outbound packets. The outer source address may be ignored.
65 * I expect an SA hash bucket, and that its per-bucket mutex is held.
66 * The SA ptr I return will have its reference count incremented by one.
69 ipsec_getassocbyconn(isaf_t
*bucket
, ip_xmit_attr_t
*ixa
, uint32_t *src
,
70 uint32_t *dst
, sa_family_t af
, uint8_t protocol
)
72 ipsa_t
*retval
, *candidate
;
73 ipsec_action_t
*candact
;
74 boolean_t need_unique
;
75 boolean_t tunnel_mode
= (ixa
->ixa_flags
& IXAF_IPSEC_TUNNEL
);
77 uint32_t old_flags
, excludeflags
;
78 ipsec_policy_t
*pp
= ixa
->ixa_ipsec_policy
;
79 ipsec_action_t
*actlist
= ixa
->ixa_ipsec_action
;
81 ipsec_latch_t
*ipl
= ixa
->ixa_ipsec_latch
;
82 ipsa_ref_t
*ipr
= NULL
;
83 sa_family_t inaf
= ixa
->ixa_ipsec_inaf
;
84 uint32_t *insrc
= ixa
->ixa_ipsec_insrc
;
85 uint32_t *indst
= ixa
->ixa_ipsec_indst
;
86 uint8_t insrcpfx
= ixa
->ixa_ipsec_insrcpfx
;
87 uint8_t indstpfx
= ixa
->ixa_ipsec_indstpfx
;
89 ASSERT(MUTEX_HELD(&bucket
->isaf_lock
));
92 * Caller must set ip_xmit_attr_t structure such that we know
93 * whether this is tunnel mode or transport mode based on
94 * IXAF_IPSEC_TUNNEL. If this flag is set, we assume that
95 * there are valid inner src and destination addresses to compare.
99 * Fast path: do we have a latch structure, is it for this bucket,
100 * and does the generation number match? If so, refhold and return.
104 ASSERT((protocol
== IPPROTO_AH
) || (protocol
== IPPROTO_ESP
));
105 ipr
= &ixa
->ixa_ipsec_ref
[protocol
- IPPROTO_ESP
];
107 retval
= ipr
->ipsr_sa
;
110 * NOTE: The isaf_gen check (incremented upon
111 * sadb_unlinkassoc()) protects against retval being a freed
112 * SA. (We're exploiting short-circuit evaluation.)
114 if ((bucket
== ipr
->ipsr_bucket
) &&
115 (bucket
->isaf_gen
== ipr
->ipsr_gen
) &&
116 (retval
->ipsa_state
!= IPSA_STATE_DEAD
) &&
117 !(retval
->ipsa_flags
& IPSA_F_CINVALID
)) {
118 IPSA_REFHOLD(retval
);
123 ASSERT((pp
!= NULL
) || (actlist
!= NULL
));
125 actlist
= pp
->ipsp_act
;
126 ASSERT(actlist
!= NULL
);
128 need_unique
= actlist
->ipa_want_unique
;
129 unique_id
= SA_FORM_UNIQUE_ID(ixa
);
132 * Precompute mask for SA flags comparison: If we need a
133 * unique SA and an SA has already been used, or if the SA has
134 * a unique value which doesn't match, we aren't interested in
138 excludeflags
= IPSA_F_UNIQUE
;
140 excludeflags
|= IPSA_F_USED
;
143 * Walk the hash bucket, matching on:
153 * Make sure that wildcard sources are inserted at the end of the hash
156 * DEFINITIONS: A _shared_ SA is one with unique_id == 0 and USED.
157 * An _unused_ SA is one with unique_id == 0 and not USED.
158 * A _unique_ SA is one with unique_id != 0 and USED.
159 * An SA with unique_id != 0 and not USED never happens.
164 for (retval
= bucket
->isaf_ipsa
; retval
!= NULL
;
165 retval
= retval
->ipsa_next
) {
166 ASSERT((candidate
== NULL
) ||
167 MUTEX_HELD(&candidate
->ipsa_lock
));
170 * Q: Should I lock this SA?
171 * A: For now, yes. I change and use too many fields in here
172 * (e.g. unique_id) that I may be racing with other threads.
173 * Also, the refcnt needs to be bumped up.
176 mutex_enter(&retval
->ipsa_lock
);
178 /* My apologies for the use of goto instead of continue. */
180 /* Outer destination address */
181 if (!IPSA_ARE_ADDR_EQUAL(dst
, retval
->ipsa_dstaddr
, af
))
182 goto next_ipsa
; /* Destination mismatch. */
184 /* Outer source address */
185 if (!IPSA_ARE_ADDR_EQUAL(src
, retval
->ipsa_srcaddr
, af
) &&
186 !IPSA_IS_ADDR_UNSPEC(retval
->ipsa_srcaddr
, af
))
187 goto next_ipsa
; /* Specific source and not matched. */
190 /* Check tunnel mode */
191 if (!(retval
->ipsa_flags
& IPSA_F_TUNNEL
))
192 goto next_ipsa
; /* Not tunnel mode SA */
194 /* Inner destination address */
195 if (!IPSA_IS_ADDR_UNSPEC(retval
->ipsa_innerdst
, inaf
)) {
196 if (!ip_addr_match((uint8_t *)indst
,
197 min(indstpfx
, retval
->ipsa_innerdstpfx
),
198 (in6_addr_t
*)retval
->ipsa_innerdst
))
199 goto next_ipsa
; /* not matched. */
202 /* Inner source address */
203 if (!IPSA_IS_ADDR_UNSPEC(retval
->ipsa_innersrc
, inaf
)) {
204 if (!ip_addr_match((uint8_t *)insrc
,
205 min(insrcpfx
, retval
->ipsa_innersrcpfx
),
206 (in6_addr_t
*)retval
->ipsa_innersrc
))
207 goto next_ipsa
; /* not matched. */
210 /* Check transport mode */
211 if (retval
->ipsa_flags
& IPSA_F_TUNNEL
)
212 goto next_ipsa
; /* Not transport mode SA */
215 * TODO - If we ever do RFC 3884's dream of transport-
216 * mode SAs with inner IP address selectors, we need
217 * to put some code here.
222 * XXX should be able to use cached/latched action
225 for (act
= actlist
; act
!= NULL
; act
= act
->ipa_next
) {
226 ipsec_act_t
*ap
= &act
->ipa_act
;
227 if (ap
->ipa_type
!= IPSEC_POLICY_APPLY
)
231 * XXX ugly. should be better way to do this test
233 if (protocol
== IPPROTO_AH
) {
234 if (!(ap
->ipa_apply
.ipp_use_ah
))
236 if (ap
->ipa_apply
.ipp_auth_alg
!=
237 retval
->ipsa_auth_alg
)
239 if (ap
->ipa_apply
.ipp_ah_minbits
>
240 retval
->ipsa_authkeybits
)
243 if (!(ap
->ipa_apply
.ipp_use_esp
))
246 if ((ap
->ipa_apply
.ipp_encr_alg
!=
247 retval
->ipsa_encr_alg
))
250 if (ap
->ipa_apply
.ipp_espe_minbits
>
251 retval
->ipsa_encrkeybits
)
254 if (ap
->ipa_apply
.ipp_esp_auth_alg
!= 0) {
255 if (ap
->ipa_apply
.ipp_esp_auth_alg
!=
256 retval
->ipsa_auth_alg
)
258 if (ap
->ipa_apply
.ipp_espa_minbits
>
259 retval
->ipsa_authkeybits
)
265 * Check key mgmt proto, cookie
267 if ((ap
->ipa_apply
.ipp_km_proto
!= 0) &&
268 (retval
->ipsa_kmp
!= 0) &&
269 (ap
->ipa_apply
.ipp_km_proto
!= retval
->ipsa_kmp
))
272 if ((ap
->ipa_apply
.ipp_km_cookie
!= 0) &&
273 (retval
->ipsa_kmc
!= 0) &&
274 (ap
->ipa_apply
.ipp_km_cookie
!= retval
->ipsa_kmc
))
280 goto next_ipsa
; /* nothing matched */
283 * Do identities match?
285 if (ipl
&& ipl
->ipl_ids_latched
&&
286 !ipsec_match_outbound_ids(ipl
, retval
))
290 * At this point, we know that we have at least a match on:
293 * - source (if source is specified, i.e. non-zeroes)
294 * - inner dest (if specified)
295 * - inner source (if specified)
296 * - auth alg (if auth alg is specified, i.e. non-zero)
297 * - encrypt. alg (if encrypt. alg is specified, i.e. non-zero)
298 * and we know that the SA keylengths are appropriate.
300 * (Keep in mind known-src SAs are hit before zero-src SAs,
301 * thanks to sadb_insertassoc().)
302 * If we need a unique asssociation, optimally we have
303 * ipsa_unique_id == unique_id, otherwise NOT USED
304 * is held in reserve (stored in candidate).
306 * For those stored in candidate, take best-match (i.e. given
307 * a choice, candidate should have non-zero ipsa_src).
311 * If SA has a unique value which matches, we're all set...
312 * "key management knows best"
314 if ((retval
->ipsa_flags
& IPSA_F_UNIQUE
) &&
315 ((unique_id
& retval
->ipsa_unique_mask
) ==
316 retval
->ipsa_unique_id
))
320 * If we need a unique SA and this SA has already been used,
321 * or if the SA has a unique value which doesn't match,
325 if (retval
->ipsa_flags
& excludeflags
)
330 * I found a candidate..
332 if (candidate
== NULL
) {
334 * and didn't already have one..
341 * If candidate's source address is zero and
342 * the current match (i.e. retval) address is
343 * not zero, we have a better candidate..
345 if (IPSA_IS_ADDR_UNSPEC(candidate
->ipsa_srcaddr
, af
) &&
346 !IPSA_IS_ADDR_UNSPEC(retval
->ipsa_srcaddr
, af
)) {
347 mutex_exit(&candidate
->ipsa_lock
);
354 mutex_exit(&retval
->ipsa_lock
);
356 ASSERT((retval
== NULL
) || MUTEX_HELD(&retval
->ipsa_lock
));
357 ASSERT((candidate
== NULL
) || MUTEX_HELD(&candidate
->ipsa_lock
));
358 ASSERT((retval
== NULL
) || (act
!= NULL
));
359 ASSERT((candidate
== NULL
) || (candact
!= NULL
));
361 /* Let caller react to a lookup failure when it gets NULL. */
362 if (retval
== NULL
&& candidate
== NULL
)
365 if (retval
== NULL
) {
366 ASSERT(MUTEX_HELD(&candidate
->ipsa_lock
));
369 } else if (candidate
!= NULL
) {
370 mutex_exit(&candidate
->ipsa_lock
);
372 ASSERT(MUTEX_HELD(&retval
->ipsa_lock
));
376 * Even though I hold the mutex, since the reference counter is an
377 * atomic operation, I really have to use the IPSA_REFHOLD macro.
379 IPSA_REFHOLD(retval
);
382 * This association is no longer unused.
384 old_flags
= retval
->ipsa_flags
;
385 retval
->ipsa_flags
|= IPSA_F_USED
;
388 * Cache a reference to this SA for the fast path.
391 ipr
->ipsr_bucket
= bucket
;
392 ipr
->ipsr_gen
= bucket
->isaf_gen
;
393 ipr
->ipsr_sa
= retval
;
394 /* I'm now caching, so the cache-invalid flag goes away! */
395 retval
->ipsa_flags
&= ~IPSA_F_CINVALID
;
398 * Latch various things while we're here..
401 if (!ipl
->ipl_ids_latched
) {
403 retval
->ipsa_src_cid
, retval
->ipsa_dst_cid
);
405 if (ixa
->ixa_ipsec_action
== NULL
) {
407 ixa
->ixa_ipsec_action
= act
;
412 * Set the uniqueness only first time.
414 if (need_unique
&& !(old_flags
& IPSA_F_USED
)) {
415 if (retval
->ipsa_unique_id
== 0) {
416 ASSERT((retval
->ipsa_flags
& IPSA_F_UNIQUE
) == 0);
418 * From now on, only this src, dst[ports, addr],
419 * proto, should use it.
421 retval
->ipsa_flags
|= IPSA_F_UNIQUE
;
422 retval
->ipsa_unique_id
= unique_id
;
423 retval
->ipsa_unique_mask
= SA_UNIQUE_MASK(
424 ixa
->ixa_ipsec_src_port
, ixa
->ixa_ipsec_dst_port
,
429 * Set the source address and adjust the hash
430 * buckets only if src_addr is zero.
432 if (IPSA_IS_ADDR_UNSPEC(retval
->ipsa_srcaddr
, af
)) {
434 * sadb_unlinkassoc() will decrement the refcnt. Bump
435 * up when we have the lock so that we don't have to
436 * acquire locks when we come back from
437 * sadb_insertassoc().
439 * We don't need to bump the bucket's gen since
440 * we aren't moving to a new bucket.
442 IPSA_REFHOLD(retval
);
443 IPSA_COPY_ADDR(retval
->ipsa_srcaddr
, src
, af
);
444 mutex_exit(&retval
->ipsa_lock
);
445 sadb_unlinkassoc(retval
);
447 * Since the bucket lock is held, we know
448 * sadb_insertassoc() will succeed.
451 if (sadb_insertassoc(retval
, bucket
) != 0) {
453 "sadb_insertassoc() failed in "
454 "ipsec_getassocbyconn().\n");
456 #else /* non-DEBUG */
457 (void) sadb_insertassoc(retval
, bucket
);
462 mutex_exit(&retval
->ipsa_lock
);
468 * Look up a security association based on the security parameters index (SPI)
469 * and address(es). This is used for inbound packets and general SA lookups
470 * (even in outbound SA tables). The source address may be ignored. Return
471 * NULL if no association is available. If an SA is found, return it, with
472 * its refcnt incremented. The caller must REFRELE after using the SA.
473 * The hash bucket must be locked down before calling.
476 ipsec_getassocbyspi(isaf_t
*bucket
, uint32_t spi
, uint32_t *src
, uint32_t *dst
,
481 ASSERT(MUTEX_HELD(&bucket
->isaf_lock
));
484 * Walk the hash bucket, matching exactly on SPI, then destination,
487 * Per-SA locking doesn't need to happen, because I'm only matching
488 * on addresses. Addresses are only changed during insertion/deletion
489 * from the hash bucket. Since the hash bucket lock is held, we don't
490 * need to worry about addresses changing.
493 for (retval
= bucket
->isaf_ipsa
; retval
!= NULL
;
494 retval
= retval
->ipsa_next
) {
495 if (retval
->ipsa_spi
!= spi
)
497 if (!IPSA_ARE_ADDR_EQUAL(dst
, retval
->ipsa_dstaddr
, af
))
501 * Assume that wildcard source addresses are inserted at the
502 * end of the hash bucket. (See sadb_insertassoc().)
503 * The following check for source addresses is a weak form
504 * of access control/source identity verification. If an
505 * SA has a source address, I only match an all-zeroes
506 * source address, or that particular one. If the SA has
507 * an all-zeroes source, then I match regardless.
509 * There is a weakness here in that a packet with all-zeroes
510 * for an address will match regardless of the source address
511 * stored in the packet.
513 * Note that port-level packet selectors, if present,
514 * are checked in ipsec_check_ipsecin_unique().
516 if (IPSA_ARE_ADDR_EQUAL(src
, retval
->ipsa_srcaddr
, af
) ||
517 IPSA_IS_ADDR_UNSPEC(retval
->ipsa_srcaddr
, af
) ||
518 IPSA_IS_ADDR_UNSPEC(src
, af
))
522 if (retval
!= NULL
) {
524 * Just refhold the return value. The caller will then
525 * make the appropriate calls to set the USED flag.
527 IPSA_REFHOLD(retval
);
534 ipsec_outbound_sa(mblk_t
*data_mp
, ip_xmit_attr_t
*ixa
, uint_t proto
)
537 uint32_t *dst_ptr
, *src_ptr
;
546 ip_stack_t
*ipst
= ixa
->ixa_ipst
;
547 netstack_t
*ns
= ipst
->ips_netstack
;
549 ASSERT(ixa
->ixa_flags
& IXAF_IPSEC_SECURE
);
551 if (proto
== IPPROTO_ESP
) {
552 ipsecesp_stack_t
*espstack
;
554 espstack
= ns
->netstack_ipsecesp
;
555 sa
= &ixa
->ixa_ipsec_esp_sa
;
556 sadbp
= &espstack
->esp_sadb
;
558 ipsecah_stack_t
*ahstack
;
560 ASSERT(proto
== IPPROTO_AH
);
561 ahstack
= ns
->netstack_ipsecah
;
562 sa
= &ixa
->ixa_ipsec_ah_sa
;
563 sadbp
= &ahstack
->ah_sadb
;
568 if (ixa
->ixa_flags
& IXAF_IS_IPV4
) {
569 ipha_t
*ipha
= (ipha_t
*)data_mp
->b_rptr
;
571 ASSERT(IPH_HDR_VERSION(ipha
) == IPV4_VERSION
);
572 dst
= ip_get_dst(ipha
);
577 * NOTE:Getting the outbound association is considerably
578 * painful. ipsec_getassocbyconn() will require more
579 * parameters as policy implementations mature.
581 bucket
= OUTBOUND_BUCKET_V4(sp
, dst
);
582 src_ptr
= (uint32_t *)&ipha
->ipha_src
;
583 dst_ptr
= (uint32_t *)&dst
;
585 ip6_t
*ip6h
= (ip6_t
*)data_mp
->b_rptr
;
587 ASSERT(IPH_HDR_VERSION(ip6h
) == IPV6_VERSION
);
588 dst6
= ip_get_dst_v6(ip6h
, data_mp
, NULL
);
591 bzero(&ipp
, sizeof (ipp
));
594 /* Same NOTE: applies here! */
595 bucket
= OUTBOUND_BUCKET_V6(sp
, dst6
);
596 src_ptr
= (uint32_t *)&ip6h
->ip6_src
;
597 dst_ptr
= (uint32_t *)&dst6
;
600 mutex_enter(&bucket
->isaf_lock
);
601 assoc
= ipsec_getassocbyconn(bucket
, ixa
, src_ptr
, dst_ptr
, af
,
603 mutex_exit(&bucket
->isaf_lock
);
608 if (assoc
->ipsa_state
== IPSA_STATE_DEAD
) {
613 ASSERT(assoc
->ipsa_state
!= IPSA_STATE_LARVAL
);
620 * Inbound IPsec SA selection.
621 * Can return a pulled up mblk.
622 * When it returns non-NULL ahp is updated
625 ipsec_inbound_ah_sa(mblk_t
*mp
, ip_recv_attr_t
*ira
, ah_t
**ahp
)
634 uint32_t *src_ptr
, *dst_ptr
;
638 netstack_t
*ns
= ira
->ira_ill
->ill_ipst
->ips_netstack
;
639 ipsec_stack_t
*ipss
= ns
->netstack_ipsec
;
640 ipsecah_stack_t
*ahstack
= ns
->netstack_ipsecah
;
642 IP_AH_BUMP_STAT(ipss
, in_requests
);
644 isv6
= !(ira
->ira_flags
& IRAF_IS_IPV4
);
646 ip6h
= (ip6_t
*)mp
->b_rptr
;
647 ah_offset
= ipsec_ah_get_hdr_size_v6(mp
, B_TRUE
);
649 ipha
= (ipha_t
*)mp
->b_rptr
;
650 ASSERT(ipha
->ipha_protocol
== IPPROTO_AH
);
651 ah_offset
= ipha
->ipha_version_and_hdr_length
-
652 (uint8_t)((IP_VERSION
<< 4));
657 * We assume that the IP header is pulled up until
658 * the options. We need to see whether we have the
659 * AH header in the same mblk or not.
661 pullup_len
= ah_offset
+ sizeof (ah_t
);
662 if (mp
->b_rptr
+ pullup_len
> mp
->b_wptr
) {
663 if (!pullupmsg(mp
, pullup_len
)) {
664 ipsec_rl_strlog(ns
, ip_mod_info
.mi_idnum
, 0, 0,
666 "ipsec_inbound_ah_sa: Small AH header\n");
667 IP_AH_BUMP_STAT(ipss
, in_discards
);
668 ip_drop_packet(mp
, B_TRUE
, ira
->ira_ill
,
669 DROPPER(ipss
, ipds_ah_bad_length
),
670 &ipss
->ipsec_dropper
);
674 ip6h
= (ip6_t
*)mp
->b_rptr
;
676 ipha
= (ipha_t
*)mp
->b_rptr
;
679 ah
= (ah_t
*)(mp
->b_rptr
+ ah_offset
);
682 src_ptr
= (uint32_t *)&ip6h
->ip6_src
;
683 dst_ptr
= (uint32_t *)&ip6h
->ip6_dst
;
684 sp
= &ahstack
->ah_sadb
.s_v6
;
687 src_ptr
= (uint32_t *)&ipha
->ipha_src
;
688 dst_ptr
= (uint32_t *)&ipha
->ipha_dst
;
689 sp
= &ahstack
->ah_sadb
.s_v4
;
693 hptr
= INBOUND_BUCKET(sp
, ah
->ah_spi
);
694 mutex_enter(&hptr
->isaf_lock
);
695 assoc
= ipsec_getassocbyspi(hptr
, ah
->ah_spi
, src_ptr
, dst_ptr
, af
);
696 mutex_exit(&hptr
->isaf_lock
);
698 if (assoc
== NULL
|| assoc
->ipsa_state
== IPSA_STATE_DEAD
||
699 assoc
->ipsa_state
== IPSA_STATE_ACTIVE_ELSEWHERE
) {
700 IP_AH_BUMP_STAT(ipss
, lookup_failure
);
701 IP_AH_BUMP_STAT(ipss
, in_discards
);
702 ipsecah_in_assocfailure(mp
, 0,
703 SL_ERROR
| SL_CONSOLE
| SL_WARN
,
704 "ipsec_inbound_ah_sa: No association found for "
705 "spi 0x%x, dst addr %s\n",
706 ah
->ah_spi
, dst_ptr
, af
, ira
);
713 if (assoc
->ipsa_state
== IPSA_STATE_LARVAL
) {
714 /* Not fully baked; swap the packet under a rock until then */
716 mp
= sadb_set_lpkt(assoc
, mp
, ira
);
721 /* Looks like the SA is no longer LARVAL. */
724 /* Are the IPsec fields initialized at all? */
725 if (!(ira
->ira_flags
& IRAF_IPSEC_SECURE
)) {
726 ira
->ira_ipsec_action
= NULL
;
727 ira
->ira_ipsec_ah_sa
= NULL
;
728 ira
->ira_ipsec_esp_sa
= NULL
;
732 * Save a reference to the association so that it can
733 * be retrieved after execution. We free any AH SA reference
734 * already there (innermost SA "wins". The reference to
735 * the SA will also be used later when doing the policy checks.
737 if (ira
->ira_ipsec_ah_sa
!= NULL
) {
738 IPSA_REFRELE(ira
->ira_ipsec_ah_sa
);
740 ira
->ira_flags
|= IRAF_IPSEC_SECURE
;
741 ira
->ira_ipsec_ah_sa
= assoc
;
748 * Can return a pulled up mblk.
749 * When it returns non-NULL esphp is updated
752 ipsec_inbound_esp_sa(mblk_t
*data_mp
, ip_recv_attr_t
*ira
, esph_t
**esphp
)
755 uint32_t *src_ptr
, *dst_ptr
;
765 netstack_t
*ns
= ira
->ira_ill
->ill_ipst
->ips_netstack
;
766 ipsec_stack_t
*ipss
= ns
->netstack_ipsec
;
767 ipsecesp_stack_t
*espstack
= ns
->netstack_ipsecesp
;
769 IP_ESP_BUMP_STAT(ipss
, in_requests
);
771 isv6
= !(ira
->ira_flags
& IRAF_IS_IPV4
);
773 ip6h
= (ip6_t
*)data_mp
->b_rptr
;
775 ipha
= (ipha_t
*)data_mp
->b_rptr
;
779 * Put all data into one mblk if it's not there already.
780 * XXX This is probably bad long-term. Figure out better ways of doing
781 * this. Much of the inbound path depends on all of the data being
784 * XXX Jumbogram issues will have to be dealt with here.
785 * If the plen is 0, we'll have to scan for a HBH header with the
786 * actual packet length.
788 if (data_mp
->b_datap
->db_ref
> 1 ||
789 (data_mp
->b_wptr
- data_mp
->b_rptr
) < ira
->ira_pktlen
) {
790 placeholder
= msgpullup(data_mp
, -1);
791 if (placeholder
== NULL
) {
792 IP_ESP_BUMP_STAT(ipss
, in_discards
);
793 ip_drop_packet(data_mp
, B_TRUE
, ira
->ira_ill
,
794 DROPPER(ipss
, ipds_esp_nomem
),
795 &ipss
->ipsec_dropper
);
798 /* Reset packet with new pulled up mblk. */
800 data_mp
= placeholder
;
805 * Find the ESP header, point the address pointers at the appropriate
809 ip6h
= (ip6_t
*)data_mp
->b_rptr
;
810 src_ptr
= (uint32_t *)&ip6h
->ip6_src
;
811 dst_ptr
= (uint32_t *)&ip6h
->ip6_dst
;
812 if (ip6h
->ip6_nxt
!= IPPROTO_ESP
) {
813 /* There are options that need to be processed. */
814 preamble
= ip_hdr_length_v6(data_mp
, ip6h
);
816 preamble
= sizeof (ip6_t
);
819 sp
= &espstack
->esp_sadb
.s_v6
;
822 ipha
= (ipha_t
*)data_mp
->b_rptr
;
823 src_ptr
= (uint32_t *)&ipha
->ipha_src
;
824 dst_ptr
= (uint32_t *)&ipha
->ipha_dst
;
825 preamble
= IPH_HDR_LENGTH(ipha
);
827 sp
= &espstack
->esp_sadb
.s_v4
;
831 esph
= (esph_t
*)(data_mp
->b_rptr
+ preamble
);
833 /* Since hash is common on inbound (SPI value), hash here. */
834 bucket
= INBOUND_BUCKET(sp
, esph
->esph_spi
);
835 mutex_enter(&bucket
->isaf_lock
);
836 ipsa
= ipsec_getassocbyspi(bucket
, esph
->esph_spi
, src_ptr
, dst_ptr
,
838 mutex_exit(&bucket
->isaf_lock
);
840 if (ipsa
== NULL
|| ipsa
->ipsa_state
== IPSA_STATE_DEAD
||
841 ipsa
->ipsa_state
== IPSA_STATE_ACTIVE_ELSEWHERE
) {
842 /* This is a loggable error! AUDIT ME! */
843 IP_ESP_BUMP_STAT(ipss
, lookup_failure
);
844 IP_ESP_BUMP_STAT(ipss
, in_discards
);
845 ipsecesp_in_assocfailure(data_mp
, 0,
846 SL_ERROR
| SL_CONSOLE
| SL_WARN
,
847 "ipsec_inbound_esp_sa: No association found for "
848 "spi 0x%x, dst addr %s\n",
849 esph
->esph_spi
, dst_ptr
, af
, ira
);
856 if (ipsa
->ipsa_state
== IPSA_STATE_LARVAL
) {
857 /* Not fully baked; swap the packet under a rock until then */
859 data_mp
= sadb_set_lpkt(ipsa
, data_mp
, ira
);
860 if (data_mp
== NULL
) {
864 /* Looks like the SA is no longer LARVAL. */
867 /* Are the IPsec fields initialized at all? */
868 if (!(ira
->ira_flags
& IRAF_IPSEC_SECURE
)) {
869 ira
->ira_ipsec_action
= NULL
;
870 ira
->ira_ipsec_ah_sa
= NULL
;
871 ira
->ira_ipsec_esp_sa
= NULL
;
875 * Save a reference to the association so that it can
876 * be retrieved after execution. We free any AH SA reference
877 * already there (innermost SA "wins". The reference to
878 * the SA will also be used later when doing the policy checks.
880 if (ira
->ira_ipsec_esp_sa
!= NULL
) {
881 IPSA_REFRELE(ira
->ira_ipsec_esp_sa
);
883 ira
->ira_flags
|= IRAF_IPSEC_SECURE
;
884 ira
->ira_ipsec_esp_sa
= ipsa
;