diff options
-rw-r--r-- | src/charon-tkm/src/tkm/tkm_kernel_sad.c | 40 | ||||
-rw-r--r-- | src/charon-tkm/src/tkm/tkm_kernel_sad.h | 11 | ||||
-rw-r--r-- | src/charon-tkm/tests/kernel_sad_tests.c | 28 |
3 files changed, 79 insertions, 0 deletions
diff --git a/src/charon-tkm/src/tkm/tkm_kernel_sad.c b/src/charon-tkm/src/tkm/tkm_kernel_sad.c index f8f23a8f8..3394b58af 100644 --- a/src/charon-tkm/src/tkm/tkm_kernel_sad.c +++ b/src/charon-tkm/src/tkm/tkm_kernel_sad.c @@ -114,6 +114,19 @@ static bool sad_entry_match(sad_entry_t * const entry, const host_t * const src, } /** + * Find a list entry with given reqid, spi and proto values. + */ +static bool sad_entry_match_dst(sad_entry_t * const entry, + const u_int32_t * const reqid, + const u_int32_t * const spi, + const u_int8_t * const proto) +{ + return entry->reqid == *reqid && + entry->spi == *spi && + entry->proto == *proto; +} + +/** * Compare two SAD entries for equality. */ static bool sad_entry_equal(sad_entry_t * const left, sad_entry_t * const right) @@ -196,6 +209,32 @@ METHOD(tkm_kernel_sad_t, get_esa_id, esa_id_type, return id; } +METHOD(tkm_kernel_sad_t, get_dst_host, host_t *, + private_tkm_kernel_sad_t * const this, const u_int32_t reqid, + const u_int32_t spi, const u_int8_t proto) +{ + host_t *dst = NULL; + sad_entry_t *entry = NULL; + + this->mutex->lock(this->mutex); + const status_t res = this->data->find_first(this->data, + (linked_list_match_t)sad_entry_match_dst, + (void**)&entry, &reqid, &spi, &proto); + if (res == SUCCESS && entry) + { + dst = entry->dst; + DBG3(DBG_KNL, "returning destination host %H of SAD entry (reqid: %u," + " spi: %x, proto: %u)", dst, reqid, ntohl(spi), proto); + } + else + { + DBG3(DBG_KNL, "no SAD entry found for reqid %u, spi %x, proto: %u", + reqid, ntohl(spi), proto); + } + this->mutex->unlock(this->mutex); + return dst; +} + METHOD(tkm_kernel_sad_t, _remove, bool, private_tkm_kernel_sad_t * const this, const esa_id_type esa_id) { @@ -250,6 +289,7 @@ tkm_kernel_sad_t *tkm_kernel_sad_create() .public = { .insert = _insert, .get_esa_id = _get_esa_id, + .get_dst_host = _get_dst_host, .remove = __remove, .destroy = _destroy, }, diff --git a/src/charon-tkm/src/tkm/tkm_kernel_sad.h b/src/charon-tkm/src/tkm/tkm_kernel_sad.h index 39388f8a8..38b19dd01 100644 --- a/src/charon-tkm/src/tkm/tkm_kernel_sad.h +++ b/src/charon-tkm/src/tkm/tkm_kernel_sad.h @@ -63,6 +63,17 @@ struct tkm_kernel_sad_t { const u_int32_t spi, const u_int8_t proto); /** + * Get destination host for entry with given parameters. + * + * @param reqid reqid of CHILD SA + * @param spi SPI of CHILD SA + * @param proto protocol of CHILD SA (ESP/AH) + * @return destination host of entry if found, NULL otherwise + */ + host_t * (*get_dst_host)(tkm_kernel_sad_t * const this, + const u_int32_t reqid, const u_int32_t spi, const u_int8_t proto); + + /** * Remove entry with given ESA id from SAD. * * @param esa_id ESA identifier of entry to remove diff --git a/src/charon-tkm/tests/kernel_sad_tests.c b/src/charon-tkm/tests/kernel_sad_tests.c index 7eb2ff8e6..b9ab3cb5e 100644 --- a/src/charon-tkm/tests/kernel_sad_tests.c +++ b/src/charon-tkm/tests/kernel_sad_tests.c @@ -81,6 +81,29 @@ START_TEST(test_get_esa_id_nonexistent) } END_TEST +START_TEST(test_get_dst_host) +{ + 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, 42, 50), + "Error inserting SAD entry"); + + host_t *dst = sad->get_dst_host(sad, 54, 42, 50); + fail_unless(addr->equals(addr, dst), "Error getting dst host"); + sad->destroy(sad); + addr->destroy(addr); +} +END_TEST + +START_TEST(test_get_dst_host_nonexistent) +{ + tkm_kernel_sad_t *sad = tkm_kernel_sad_create(); + fail_unless(sad->get_dst_host(sad, 1, 12, 50) == NULL, + "Got dst for nonexistent SAD entry"); + sad->destroy(sad); +} +END_TEST + START_TEST(test_remove) { host_t *addr = host_create_from_string("127.0.0.1", 1024); @@ -128,6 +151,11 @@ Suite *make_kernel_sad_tests() tcase_add_test(tc, test_get_esa_id_nonexistent); suite_add_tcase(s, tc); + tc = tcase_create("get_dst_host"); + tcase_add_test(tc, test_get_dst_host); + tcase_add_test(tc, test_get_dst_host_nonexistent); + suite_add_tcase(s, tc); + tc = tcase_create("remove"); tcase_add_test(tc, test_remove); tcase_add_test(tc, test_remove_nonexistent); |