diff options
Diffstat (limited to 'usr/src/uts/common/inet/ip/sadb.c')
-rw-r--r-- | usr/src/uts/common/inet/ip/sadb.c | 48 |
1 files changed, 31 insertions, 17 deletions
diff --git a/usr/src/uts/common/inet/ip/sadb.c b/usr/src/uts/common/inet/ip/sadb.c index 3d4ec0821e..6c46f53ac4 100644 --- a/usr/src/uts/common/inet/ip/sadb.c +++ b/usr/src/uts/common/inet/ip/sadb.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -6886,21 +6886,25 @@ bail: */ /* - * sadb_set_lpkt: Return TRUE if we can swap in a value to ipsa->ipsa_lpkt and - * freemsg the previous value. Return FALSE if we lost the race and the SA is - * in a non-LARVAL state. We also return FALSE if we can't allocate the attrmp. + * sadb_set_lpkt: + * + * Returns the passed-in packet if the SA is no longer larval. + * + * Returns NULL if the SA is larval, and needs to be swapped into the SA for + * processing after an SADB_UPDATE. */ -boolean_t +mblk_t * sadb_set_lpkt(ipsa_t *ipsa, mblk_t *npkt, ip_recv_attr_t *ira) { mblk_t *opkt; - netstack_t *ns = ira->ira_ill->ill_ipst->ips_netstack; - ipsec_stack_t *ipss = ns->netstack_ipsec; - boolean_t is_larval; mutex_enter(&ipsa->ipsa_lock); - is_larval = (ipsa->ipsa_state == IPSA_STATE_LARVAL); - if (is_larval) { + opkt = ipsa->ipsa_lpkt; + if (ipsa->ipsa_state == IPSA_STATE_LARVAL) { + /* + * Consume npkt and place it in the LARVAL SA's inbound + * packet slot. + */ mblk_t *attrmp; attrmp = ip_recv_attr_to_mblk(ira); @@ -6911,27 +6915,37 @@ sadb_set_lpkt(ipsa_t *ipsa, mblk_t *npkt, ip_recv_attr_t *ira) ip_drop_input("ipIfStatsInDiscards", npkt, ill); freemsg(npkt); opkt = NULL; - is_larval = B_FALSE; } else { ASSERT(attrmp->b_cont == NULL); attrmp->b_cont = npkt; - npkt = attrmp; - opkt = ipsa->ipsa_lpkt; - ipsa->ipsa_lpkt = npkt; + ipsa->ipsa_lpkt = attrmp; } + npkt = NULL; } else { - /* We lost the race. */ - opkt = NULL; + /* + * If not larval, we lost the race. NOTE: ipsa_lpkt may still + * have been non-NULL in the non-larval case, because of + * inbound packets arriving prior to sadb_common_add() + * transferring the SA completely out of larval state, but + * after lpkt was grabbed by the AH/ESP-specific add routines. + * We should clear the old ipsa_lpkt in this case to make sure + * that it doesn't linger on the now-MATURE IPsec SA, or get + * picked up as an out-of-order packet. + */ + ipsa->ipsa_lpkt = NULL; } mutex_exit(&ipsa->ipsa_lock); if (opkt != NULL) { + ipsec_stack_t *ipss; + + ipss = ira->ira_ill->ill_ipst->ips_netstack->netstack_ipsec; opkt = ip_recv_attr_free_mblk(opkt); ip_drop_packet(opkt, B_TRUE, ira->ira_ill, DROPPER(ipss, ipds_sadb_inlarval_replace), &ipss->ipsec_sadb_dropper); } - return (is_larval); + return (npkt); } /* |