charon-tkm: Don't select new outbound SA until the policy is installed
This tries to avoid packet loss during rekeying by delaying the usage of the new outbound IKE_SA until the old one is deleted. Note that esa_select() is a no-op in the current TKM implementation. And the implementation also doesn't benefit from the delayed deletion of the inbound SA as it calls esa_reset() when the outbound SA is deleted.
This commit is contained in:
parent
0d42a76275
commit
d24b831fe7
|
@ -1,7 +1,8 @@
|
|||
/*
|
||||
* Copyright (C) 2017 Tobias Brunner
|
||||
* Copyright (C) 2012-2014 Reto Buerki
|
||||
* Copyright (C) 2012 Adrian-Ken Rueegsegger
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
|
@ -182,15 +183,6 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
|
|||
tkm->chunk_map->remove(tkm->chunk_map, nonce_loc);
|
||||
tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_NONCE, nonce_loc_id);
|
||||
}
|
||||
if (ike_esa_select(esa_id) != TKM_OK)
|
||||
{
|
||||
DBG1(DBG_KNL, "error selecting new child SA (%llu)", esa_id);
|
||||
if (ike_esa_reset(esa_id) != TKM_OK)
|
||||
{
|
||||
DBG1(DBG_KNL, "child SA (%llu) deletion failed", esa_id);
|
||||
}
|
||||
goto failure;
|
||||
}
|
||||
|
||||
DBG1(DBG_KNL, "added child SA (esa: %llu, isa: %llu, esp_spi_loc: %x, "
|
||||
"esp_spi_rem: %x, role: %s)", esa_id, esa.isa_id, ntohl(spi_loc),
|
||||
|
@ -221,23 +213,12 @@ METHOD(kernel_ipsec_t, del_sa, status_t,
|
|||
private_tkm_kernel_ipsec_t *this, kernel_ipsec_sa_id_t *id,
|
||||
kernel_ipsec_del_sa_t *data)
|
||||
{
|
||||
esa_id_type esa_id, other_esa_id;
|
||||
esa_id_type esa_id;
|
||||
|
||||
esa_id = tkm->sad->get_esa_id(tkm->sad, id->src, id->dst,
|
||||
id->spi, id->proto);
|
||||
if (esa_id)
|
||||
{
|
||||
other_esa_id = tkm->sad->get_other_esa_id(tkm->sad, esa_id);
|
||||
if (other_esa_id)
|
||||
{
|
||||
DBG1(DBG_KNL, "selecting child SA (esa: %llu)", other_esa_id);
|
||||
if (ike_esa_select(other_esa_id) != TKM_OK)
|
||||
{
|
||||
DBG1(DBG_KNL, "error selecting other child SA (esa: %llu)",
|
||||
other_esa_id);
|
||||
}
|
||||
}
|
||||
|
||||
DBG1(DBG_KNL, "deleting child SA (esa: %llu, spi: %x)", esa_id,
|
||||
ntohl(id->spi));
|
||||
if (ike_esa_reset(esa_id) != TKM_OK)
|
||||
|
@ -269,6 +250,43 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
|
|||
private_tkm_kernel_ipsec_t *this, kernel_ipsec_policy_id_t *id,
|
||||
kernel_ipsec_manage_policy_t *data)
|
||||
{
|
||||
esa_id_type esa_id;
|
||||
uint32_t spi;
|
||||
uint8_t proto;
|
||||
|
||||
if (id->dir == POLICY_OUT && data->type == POLICY_IPSEC &&
|
||||
data->prio == POLICY_PRIORITY_DEFAULT)
|
||||
{
|
||||
if (data->sa->esp.use)
|
||||
{
|
||||
spi = data->sa->esp.spi;
|
||||
proto = IPPROTO_ESP;
|
||||
}
|
||||
else if (data->sa->ah.use)
|
||||
{
|
||||
spi = data->sa->ah.spi;
|
||||
proto = IPPROTO_AH;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
esa_id = tkm->sad->get_esa_id(tkm->sad, data->src, data->dst,
|
||||
spi, proto);
|
||||
if (!esa_id)
|
||||
{
|
||||
DBG1(DBG_KNL, "unable to find esa ID for policy (spi: %x)",
|
||||
ntohl(spi));
|
||||
return FAILED;
|
||||
}
|
||||
DBG1(DBG_KNL, "selecting child SA (esa: %llu, spi: %x)", esa_id,
|
||||
ntohl(spi));
|
||||
if (ike_esa_select(esa_id) != TKM_OK)
|
||||
{
|
||||
DBG1(DBG_KNL, "error selecting new child SA (%llu)", esa_id);
|
||||
return FAILED;
|
||||
}
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue