charon-tkm: Call esa_reset() when the inbound SA is deleted

After a rekeying the outbound SA and policy is deleted immediately, however,
the inbound SA is not removed until a few seconds later, so delayed packets
can still be processed.

This adds a flag to get_esa_id() that specifies the location of the
given SPI.
This commit is contained in:
Tobias Brunner
2017-08-07 10:46:00 +02:00
parent dbaeaaf605
commit 772957778c
10 changed files with 59 additions and 23 deletions
+2 -2
View File
@@ -216,7 +216,7 @@ METHOD(kernel_ipsec_t, del_sa, status_t,
esa_id_type esa_id;
esa_id = tkm->sad->get_esa_id(tkm->sad, id->src, id->dst,
id->spi, id->proto);
id->spi, id->proto, TRUE);
if (esa_id)
{
DBG1(DBG_KNL, "deleting child SA (esa: %llu, spi: %x)", esa_id,
@@ -272,7 +272,7 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
return FAILED;
}
esa_id = tkm->sad->get_esa_id(tkm->sad, data->src, data->dst,
spi, proto);
spi, proto, FALSE);
if (!esa_id)
{
DBG1(DBG_KNL, "unable to find esa ID for policy (spi: %x)",
+19 -10
View File
@@ -107,16 +107,23 @@ CALLBACK(sad_entry_match, bool,
const host_t *src, *dst;
const uint32_t *spi;
const uint8_t *proto;
const bool *local;
VA_ARGS_VGET(args, src, dst, spi, proto);
VA_ARGS_VGET(args, src, dst, spi, proto, local);
if (entry->src == NULL || entry->dst == NULL)
if (entry->src == NULL || entry->dst == NULL || entry->proto != *proto)
{
return FALSE;
}
return src->ip_equals(entry->src, (host_t *)src) &&
dst->ip_equals(entry->dst, (host_t *)dst) &&
entry->spi_rem == *spi && entry->proto == *proto;
if (*local)
{
return entry->src->ip_equals(entry->src, (host_t *)dst) &&
entry->dst->ip_equals(entry->dst, (host_t *)src) &&
entry->spi_loc == *spi;
}
return entry->src->ip_equals(entry->src, (host_t *)src) &&
entry->dst->ip_equals(entry->dst, (host_t *)dst) &&
entry->spi_rem == *spi;
}
CALLBACK(sad_entry_match_dst, bool,
@@ -193,7 +200,8 @@ METHOD(tkm_kernel_sad_t, insert, bool,
METHOD(tkm_kernel_sad_t, get_esa_id, esa_id_type,
private_tkm_kernel_sad_t * const this, const host_t * const src,
const host_t * const dst, const uint32_t spi, const uint8_t proto)
const host_t * const dst, const uint32_t spi, const uint8_t proto,
const bool local)
{
esa_id_type id = 0;
sad_entry_t *entry = NULL;
@@ -201,17 +209,18 @@ METHOD(tkm_kernel_sad_t, get_esa_id, esa_id_type,
this->mutex->lock(this->mutex);
const bool res = this->data->find_first(this->data, sad_entry_match,
(void**)&entry, src, dst, &spi,
&proto);
&proto, &local);
if (res && entry)
{
id = entry->esa_id;
DBG3(DBG_KNL, "returning ESA id %llu of SAD entry (src: %H, dst: %H, "
"spi: %x, proto: %u)", id, src, dst, ntohl(spi), proto);
"%sbound spi: %x, proto: %u)", id, src, dst, local ? "in" : "out",
ntohl(spi), proto);
}
else
{
DBG3(DBG_KNL, "no SAD entry found for src %H, dst %H, spi %x, proto %u",
src, dst, ntohl(spi), proto);
DBG3(DBG_KNL, "no SAD entry found for src %H, dst %H, %sbound spi %x, "
"proto %u", src, dst, local ? "in" : "out", ntohl(spi), proto);
}
this->mutex->unlock(this->mutex);
return id;
+3 -2
View File
@@ -55,13 +55,14 @@ struct tkm_kernel_sad_t {
*
* @param src source address of CHILD SA
* @param dst destination address of CHILD SA
* @param spi Remote SPI of CHILD SA
* @param spi SPI of CHILD SA
* @param proto protocol of CHILD SA (ESP/AH)
* @param local whether the SPI is local or remote
* @return ESA id of entry if found, 0 otherwise
*/
esa_id_type (*get_esa_id)(tkm_kernel_sad_t * const this,
const host_t * const src, const host_t * const dst,
const uint32_t spi, const uint8_t proto);
const uint32_t spi, const uint8_t proto, const bool local);
/**
* Get destination host for entry with given parameters.
+16 -2
View File
@@ -63,7 +63,20 @@ START_TEST(test_get_esa_id)
tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
fail_unless(sad->insert(sad, 23, 54, addr, addr, 27, 42, 50),
"Error inserting SAD entry");
fail_unless(sad->get_esa_id(sad, addr, addr, 42, 50) == 23,
fail_unless(sad->get_esa_id(sad, addr, addr, 42, 50, FALSE) == 23,
"Error getting esa id");
sad->destroy(sad);
addr->destroy(addr);
}
END_TEST
START_TEST(test_get_esa_id_local)
{
host_t *addr = host_create_from_string("127.0.0.1", 1024);
tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
fail_unless(sad->insert(sad, 23, 54, addr, addr, 27, 42, 50),
"Error inserting SAD entry");
fail_unless(sad->get_esa_id(sad, addr, addr, 27, 50, TRUE) == 23,
"Error getting esa id");
sad->destroy(sad);
addr->destroy(addr);
@@ -74,7 +87,7 @@ START_TEST(test_get_esa_id_nonexistent)
{
host_t *addr = host_create_from_string("127.0.0.1", 1024);
tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
fail_unless(sad->get_esa_id(sad, addr, addr, 42, 50) == 0,
fail_unless(sad->get_esa_id(sad, addr, addr, 42, 50, FALSE) == 0,
"Got esa id for nonexistent SAD entry");
sad->destroy(sad);
addr->destroy(addr);
@@ -148,6 +161,7 @@ Suite *make_kernel_sad_tests()
tc = tcase_create("get_esa_id");
tcase_add_test(tc, test_get_esa_id);
tcase_add_test(tc, test_get_esa_id_local);
tcase_add_test(tc, test_get_esa_id_nonexistent);
suite_add_tcase(s, tc);