From: Tobias Brunner Date: Thu, 16 Dec 2021 12:50:38 +0000 (+0100) Subject: kernel-listener: Use a struct to pass data from acquires X-Git-Tag: 5.9.6rc1~3^2~43 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3b699c720f16ee785913ca201d71427159dc7c80;p=thirdparty%2Fstrongswan.git kernel-listener: Use a struct to pass data from acquires --- diff --git a/src/charon-tkm/src/ees/ees_callbacks.c b/src/charon-tkm/src/ees/ees_callbacks.c index 863f618bc2..304f4cac3b 100644 --- a/src/charon-tkm/src/ees/ees_callbacks.c +++ b/src/charon-tkm/src/ees/ees_callbacks.c @@ -24,8 +24,10 @@ void charon_esa_acquire(result_type *res, const sp_id_type sp_id) { + kernel_acquire_data_t data = {}; + DBG1(DBG_KNL, "ees: acquire received for reqid %u", sp_id); - charon->kernel->acquire(charon->kernel, sp_id, NULL, NULL); + charon->kernel->acquire(charon->kernel, sp_id, &data); *res = TKM_OK; } diff --git a/src/libcharon/kernel/kernel_handler.c b/src/libcharon/kernel/kernel_handler.c index 006304d5eb..4f467efee9 100644 --- a/src/libcharon/kernel/kernel_handler.c +++ b/src/libcharon/kernel/kernel_handler.c @@ -53,20 +53,19 @@ static inline protocol_id_t proto_ip2ike(uint8_t protocol) } METHOD(kernel_listener_t, acquire, bool, - private_kernel_handler_t *this, uint32_t reqid, - traffic_selector_t *src_ts, traffic_selector_t *dst_ts) + private_kernel_handler_t *this, uint32_t reqid, kernel_acquire_data_t *data) { - if (src_ts && dst_ts) + if (data->src && data->dst) { DBG1(DBG_KNL, "creating acquire job for policy %R === %R with " - "reqid {%u}", src_ts, dst_ts, reqid); + "reqid {%u}", data->src, data->dst, reqid); } else { DBG1(DBG_KNL, "creating acquire job for policy with reqid {%u}", reqid); } lib->processor->queue_job(lib->processor, - (job_t*)acquire_job_create(reqid, src_ts, dst_ts)); + (job_t*)acquire_job_create(reqid, data)); return TRUE; } diff --git a/src/libcharon/kernel/kernel_interface.c b/src/libcharon/kernel/kernel_interface.c index 300796f8e3..8f6c21b615 100644 --- a/src/libcharon/kernel/kernel_interface.c +++ b/src/libcharon/kernel/kernel_interface.c @@ -827,7 +827,7 @@ METHOD(kernel_interface_t, remove_listener, void, METHOD(kernel_interface_t, acquire, void, private_kernel_interface_t *this, uint32_t reqid, - traffic_selector_t *src_ts, traffic_selector_t *dst_ts) + kernel_acquire_data_t *data) { kernel_listener_t *listener; enumerator_t *enumerator; @@ -835,8 +835,7 @@ METHOD(kernel_interface_t, acquire, void, enumerator = this->listeners->create_enumerator(this->listeners); while (enumerator->enumerate(enumerator, &listener)) { - if (listener->acquire && - !listener->acquire(listener, reqid, src_ts, dst_ts)) + if (listener->acquire && !listener->acquire(listener, reqid, data)) { this->listeners->remove_at(this->listeners, enumerator); } diff --git a/src/libcharon/kernel/kernel_interface.h b/src/libcharon/kernel/kernel_interface.h index 50c1cac535..dbc863736b 100644 --- a/src/libcharon/kernel/kernel_interface.h +++ b/src/libcharon/kernel/kernel_interface.h @@ -513,11 +513,10 @@ struct kernel_interface_t { * Raise an acquire event. * * @param reqid reqid of the policy to acquire - * @param src_ts source traffic selector - * @param dst_ts destination traffic selector + * @param data data from the acquire */ void (*acquire)(kernel_interface_t *this, uint32_t reqid, - traffic_selector_t *src_ts, traffic_selector_t *dst_ts); + kernel_acquire_data_t *data); /** * Raise an expire event. diff --git a/src/libcharon/kernel/kernel_listener.h b/src/libcharon/kernel/kernel_listener.h index 71868511f7..6534921c24 100644 --- a/src/libcharon/kernel/kernel_listener.h +++ b/src/libcharon/kernel/kernel_listener.h @@ -22,12 +22,23 @@ #define KERNEL_LISTENER_H_ typedef struct kernel_listener_t kernel_listener_t; +typedef struct kernel_acquire_data_t kernel_acquire_data_t; #include #include #include #include +/** + * Data received with a kernel's acquire, has to be cloned/copied by listener. + */ +struct kernel_acquire_data_t { + /** Optional source of the triggering packet */ + traffic_selector_t *src; + /** Optional destination of the triggering packet */ + traffic_selector_t *dst; +}; + /** * Interface for components interested in kernel events. * @@ -39,12 +50,11 @@ struct kernel_listener_t { * Hook called if an acquire event for a policy is received. * * @param reqid reqid of the policy to acquire - * @param src_ts source traffic selector - * @param dst_ts destination traffic selector + * @param data data from the acquire * @return TRUE to remain registered, FALSE to unregister */ bool (*acquire)(kernel_listener_t *this, uint32_t reqid, - traffic_selector_t *src_ts, traffic_selector_t *dst_ts); + kernel_acquire_data_t *data); /** * Hook called if an expire event for an IPsec SA is received. diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c index 32b6853450..c3c6d60350 100644 --- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c +++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c @@ -897,7 +897,7 @@ static void process_acquire(private_kernel_netlink_ipsec_t *this, struct xfrm_user_acquire *acquire; struct rtattr *rta; size_t rtasize; - traffic_selector_t *src_ts, *dst_ts; + kernel_acquire_data_t data = {}; uint32_t reqid = 0; uint8_t proto; @@ -930,10 +930,13 @@ static void process_acquire(private_kernel_netlink_ipsec_t *this, /* acquire for AH/ESP only, not for IPCOMP */ return; } - src_ts = selector2ts(&acquire->sel, TRUE); - dst_ts = selector2ts(&acquire->sel, FALSE); + data.src = selector2ts(&acquire->sel, TRUE); + data.dst = selector2ts(&acquire->sel, FALSE); + + charon->kernel->acquire(charon->kernel, reqid, &data); - charon->kernel->acquire(charon->kernel, reqid, src_ts, dst_ts); + DESTROY_IF(data.src); + DESTROY_IF(data.dst); } /** diff --git a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c index f32c4f83d8..3243d1e946 100644 --- a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c +++ b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c @@ -1318,8 +1318,8 @@ static void process_acquire(private_kernel_pfkey_ipsec_t *this, struct sadb_msg* msg) { pfkey_msg_t response; + kernel_acquire_data_t data = {}; uint32_t index, reqid = 0; - traffic_selector_t *src_ts, *dst_ts; policy_entry_t *policy; policy_sa_t *sa; @@ -1363,10 +1363,16 @@ static void process_acquire(private_kernel_pfkey_ipsec_t *this, this->mutex->unlock(this->mutex); } - src_ts = sadb_address2ts(response.src); - dst_ts = sadb_address2ts(response.dst); + if (reqid) + { + data.src = sadb_address2ts(response.src); + data.dst = sadb_address2ts(response.dst); + + charon->kernel->acquire(charon->kernel, reqid, &data); - charon->kernel->acquire(charon->kernel, reqid, src_ts, dst_ts); + data.src->destroy(data.src); + data.dst->destroy(data.dst); + } } /** diff --git a/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c b/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c index 19d4f3ef4c..36f5a97fc6 100644 --- a/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c +++ b/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c @@ -1634,6 +1634,7 @@ static u_int hash_trap(trap_t *trap) static void acquire(private_kernel_wfp_ipsec_t *this, UINT64 filter_id, traffic_selector_t *src, traffic_selector_t *dst) { + kernel_acquire_data_t data = {}; uint32_t reqid = 0; trap_t *trap, key = { .filter_id = filter_id, @@ -1649,9 +1650,13 @@ static void acquire(private_kernel_wfp_ipsec_t *this, UINT64 filter_id, if (reqid) { - src = src ? src->clone(src) : NULL; - dst = dst ? dst->clone(dst) : NULL; - charon->kernel->acquire(charon->kernel, reqid, src, dst); + data.src = src ? src->clone(src) : NULL; + data.dst = dst ? dst->clone(dst) : NULL; + + charon->kernel->acquire(charon->kernel, reqid, &data); + + DESTROY_IF(data.src); + DESTROY_IF(data.dst); } } diff --git a/src/libcharon/processing/jobs/acquire_job.c b/src/libcharon/processing/jobs/acquire_job.c index c92c03f8fd..0f06fcfcd4 100644 --- a/src/libcharon/processing/jobs/acquire_job.c +++ b/src/libcharon/processing/jobs/acquire_job.c @@ -30,34 +30,28 @@ struct private_acquire_job_t { acquire_job_t public; /** - * reqid of the child to rekey + * reqid of the triggered policy */ uint32_t reqid; /** - * acquired source traffic selector + * Data from the acquire */ - traffic_selector_t *src_ts; - - /** - * acquired destination traffic selector - */ - traffic_selector_t *dst_ts; + kernel_acquire_data_t data; }; METHOD(job_t, destroy, void, private_acquire_job_t *this) { - DESTROY_IF(this->src_ts); - DESTROY_IF(this->dst_ts); + DESTROY_IF(this->data.src); + DESTROY_IF(this->data.dst); free(this); } METHOD(job_t, execute, job_requeue_t, private_acquire_job_t *this) { - charon->traps->acquire(charon->traps, this->reqid, - this->src_ts, this->dst_ts); + charon->traps->acquire(charon->traps, this->reqid, &this->data); return JOB_REQUEUE_NONE; } @@ -70,9 +64,7 @@ METHOD(job_t, get_priority, job_priority_t, /* * Described in header */ -acquire_job_t *acquire_job_create(uint32_t reqid, - traffic_selector_t *src_ts, - traffic_selector_t *dst_ts) +acquire_job_t *acquire_job_create(uint32_t reqid, kernel_acquire_data_t *data) { private_acquire_job_t *this; @@ -85,10 +77,18 @@ acquire_job_t *acquire_job_create(uint32_t reqid, }, }, .reqid = reqid, - .src_ts = src_ts, - .dst_ts = dst_ts, + .data = *data, ); + if (this->data.src) + { + this->data.src = this->data.src->clone(this->data.src); + } + if (this->data.dst) + { + this->data.dst = this->data.dst->clone(this->data.dst); + } + return &this->public; } diff --git a/src/libcharon/processing/jobs/acquire_job.h b/src/libcharon/processing/jobs/acquire_job.h index d45f72b46b..f6b4723979 100644 --- a/src/libcharon/processing/jobs/acquire_job.h +++ b/src/libcharon/processing/jobs/acquire_job.h @@ -24,7 +24,7 @@ typedef struct acquire_job_t acquire_job_t; #include -#include +#include #include /** @@ -42,13 +42,10 @@ struct acquire_job_t { /** * Creates a job of type ACQUIRE. * - * @param reqid reqid of the trapped CHILD_SA to acquire - * @param src_ts source traffic selector - * @param dst_ts destination traffic selector + * @param reqid reqid of the triggered policy + * @param data data from the acquire * @return acquire_job_t object */ -acquire_job_t *acquire_job_create(uint32_t reqid, - traffic_selector_t *src_ts, - traffic_selector_t *dst_ts); +acquire_job_t *acquire_job_create(uint32_t reqid, kernel_acquire_data_t *data); #endif /** REKEY_CHILD_SA_JOB_H_ @}*/ diff --git a/src/libcharon/sa/trap_manager.c b/src/libcharon/sa/trap_manager.c index fc78eb441d..b00f7edc97 100644 --- a/src/libcharon/sa/trap_manager.c +++ b/src/libcharon/sa/trap_manager.c @@ -423,8 +423,7 @@ METHOD(trap_manager_t, create_enumerator, enumerator_t*, } METHOD(trap_manager_t, acquire, void, - private_trap_manager_t *this, uint32_t reqid, - traffic_selector_t *src, traffic_selector_t *dst) + private_trap_manager_t *this, uint32_t reqid, kernel_acquire_data_t *data) { enumerator_t *enumerator; entry_t *entry, *found = NULL; @@ -454,7 +453,6 @@ METHOD(trap_manager_t, acquire, void, this->lock->unlock(this->lock); return; } - reqid = found->child_sa->get_reqid(found->child_sa); wildcard = found->wildcard; this->mutex->lock(this->mutex); @@ -463,7 +461,7 @@ METHOD(trap_manager_t, acquire, void, * with the same peer */ uint8_t mask; - dst->to_subnet(dst, &host, &mask); + data->dst->to_subnet(data->dst, &host, &mask); if (this->acquires->find_first(this->acquires, acquire_by_dst, (void**)&acquire, host)) { @@ -497,7 +495,8 @@ METHOD(trap_manager_t, acquire, void, this->mutex->unlock(this->mutex); if (ignore) { - DBG1(DBG_CFG, "ignoring acquire, connection attempt pending"); + DBG1(DBG_CFG, "ignoring acquire for reqid %u, connection attempt " + "pending", reqid); this->lock->unlock(this->lock); return; } @@ -521,12 +520,12 @@ METHOD(trap_manager_t, acquire, void, ike_cfg = ike_sa->get_ike_cfg(ike_sa); port = ike_cfg->get_other_port(ike_cfg); - dst->to_subnet(dst, &host, &mask); + data->dst->to_subnet(data->dst, &host, &mask); host->set_port(host, port); ike_sa->set_other_host(ike_sa, host); port = ike_cfg->get_my_port(ike_cfg); - src->to_subnet(src, &host, &mask); + data->src->to_subnet(data->src, &host, &mask); host->set_port(host, port); ike_sa->set_my_host(ike_sa, host); @@ -544,8 +543,8 @@ METHOD(trap_manager_t, acquire, void, { child_init_args_t args = { .reqid = reqid, - .src = src, - .dst = dst, + .src = data->src, + .dst = data->dst, }; if (this->ignore_acquire_ts || ike_sa->get_version(ike_sa) == IKEV1) diff --git a/src/libcharon/sa/trap_manager.h b/src/libcharon/sa/trap_manager.h index f226798fc2..d9b4906f74 100644 --- a/src/libcharon/sa/trap_manager.h +++ b/src/libcharon/sa/trap_manager.h @@ -64,12 +64,11 @@ struct trap_manager_t { /** * Acquire an SA triggered by an installed trap. * - * @param reqid reqid of the triggering CHILD_SA - * @param src source of the triggering packet - * @param dst destination of the triggering packet + * @param reqid reqid of the triggered policy + * @param data data from the acquire */ void (*acquire)(trap_manager_t *this, uint32_t reqid, - traffic_selector_t *src, traffic_selector_t *dst); + kernel_acquire_data_t *data); /** * Clear any installed trap.