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:
@@ -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)",
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user