FreeBSD/sys/netipsec/key.c
/*
 * allocating an SA entry for an *OUTBOUND* packet.
 * checking each request entries in SP, and acquire an SA if need.
 * OUT:	0: there are valid requests.
 *	ENOENT: policy may be valid, but SA with REQUIRE is on acquiring.
 */
allocating an SA entry for an *OUTBOUND* packet.
checking each request entries in SP, and acquire an SA if need.
OUT: 0: there are valid requests.
ENOENT: policy may be valid, but SA with REQUIRE is on acquiring.
allocating an SA entry for an * OUTBOUND * packet . checking each request entries in SP and acquire an SA if need . OUT : 0 : there are valid requests . ENOENT : policy may be valid but SA with REQUIRE is on acquiring .
int
key_checkrequest(struct ipsecrequest *isr, const struct secasindex *saidx)
{
	u_int level;
	int error;
	struct secasvar *sav;
	IPSEC_ASSERT(isr != NULL, ("null isr"));
	IPSEC_ASSERT(saidx != NULL, ("null saidx"));
	IPSEC_ASSERT(saidx->mode == IPSEC_MODE_TRANSPORT ||
		saidx->mode == IPSEC_MODE_TUNNEL,
		("unexpected policy %u", saidx->mode));
	IPSECREQUEST_LOCK_ASSERT(isr);
	level = ipsec_get_reqlevel(isr);
	sav = key_allocsa_policy(saidx);
	if (sav != isr->sav) {
		if (!IPSECREQUEST_UPGRADE(isr)) {
			IPSECREQUEST_UNLOCK(isr);
			IPSECREQUEST_WLOCK(isr);
		}
		if (isr->sav != NULL)
			KEY_FREESAV(&isr->sav);
		isr->sav = sav;
		IPSECREQUEST_DOWNGRADE(isr);
	} else if (sav != NULL)
		KEY_FREESAV(&sav);
	if (isr->sav != NULL) {
		if (isr->sav->state != SADB_SASTATE_MATURE &&
		    isr->sav->state != SADB_SASTATE_DYING)
			return EINVAL;
		return 0;
	}
	error = key_acquire(saidx, isr->sp);
	if (error != 0) {
		ipseclog((LOG_DEBUG, "%s: error %d returned from key_acquire\n",
			__func__, error));
		return error;
	}
	if (level != IPSEC_LEVEL_REQUIRE) {
		IPSEC_ASSERT(isr->sav == NULL, ("unexpected SA"));
		return 0;
	} else {
		return ENOENT;
	}
}
int key_checkrequest ( struct ipsecrequest * isr , const struct secasindex * saidx ) { u_int level ; int error ; struct secasvar * sav ; IPSEC_ASSERT ( isr != NULL , ( " " ) ) ; IPSEC_ASSERT ( saidx != NULL , ( " " ) ) ; IPSEC_ASSERT ( saidx -> mode == IPSEC_MODE_TRANSPORT || saidx -> mode == IPSEC_MODE_TUNNEL , ( " " , saidx -> mode ) ) ; IPSECREQUEST_LOCK_ASSERT ( isr ) ; level = ipsec_get_reqlevel ( isr ) ; sav = key_allocsa_policy ( saidx ) ; if ( sav != isr -> sav ) { if ( ! IPSECREQUEST_UPGRADE ( isr ) ) { IPSECREQUEST_UNLOCK ( isr ) ; IPSECREQUEST_WLOCK ( isr ) ; } if ( isr -> sav != NULL ) KEY_FREESAV ( & isr -> sav ) ; isr -> sav = sav ; IPSECREQUEST_DOWNGRADE ( isr ) ; } else if ( sav != NULL ) KEY_FREESAV ( & sav ) ; if ( isr -> sav != NULL ) { if ( isr -> sav -> state != SADB_SASTATE_MATURE && isr -> sav -> state != SADB_SASTATE_DYING ) return EINVAL ; return 0 ; } error = key_acquire ( saidx , isr -> sp ) ; if ( error != 0 ) { ipseclog ( ( LOG_DEBUG , " \n " , __func__ , error ) ) ; return error ; } if ( level != IPSEC_LEVEL_REQUIRE ) { IPSEC_ASSERT ( isr -> sav == NULL , ( " " ) ) ; return 0 ; } else { return ENOENT ; } }
allocating an SA entry for an *OUTBOUND* packet.
allocating an SA entry for an * OUTBOUND * packet .
/*
	 * XXX guard against protocol callbacks from the crypto
	 * thread as they reference ipsecrequest.sav which we
	 * temporarily null out below.  Need to rethink how we
	 * handle bundled SA's in the callback thread.
	 */ /* get current level */ /*
	 * We check new SA in the IPsec request because a different
	 * SA may be involved each time this request is checked, either
	 * because new SAs are being configured, or this request is
	 * associated with an unconnected datagram socket, or this request
	 * is associated with a system default policy.
	 *
	 * key_allocsa_policy should allocate the oldest SA available.
	 * See key_do_allocsa_policy(), and draft-jenkins-ipsec-rekeying-03.txt.
	 */ /* SA need to be updated. */ /* Kick everyone off. */ /* When there is SA. */ /* there is no SA */ /* XXX What should I do ? */ /* XXX sigh, the interface to this routine is botched */