kernel-listener: Use a struct to pass data from acquires

This commit is contained in:
Tobias Brunner 2021-12-16 13:50:38 +01:00
parent 9983326b20
commit 3b699c720f
12 changed files with 81 additions and 63 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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.

View File

@ -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 <networking/host.h>
#include <networking/tun_device.h>
#include <selectors/traffic_selector.h>
#include <kernel/kernel_ipsec.h>
/**
* 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.

View File

@ -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, src_ts, dst_ts);
charon->kernel->acquire(charon->kernel, reqid, &data);
DESTROY_IF(data.src);
DESTROY_IF(data.dst);
}
/**

View File

@ -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, src_ts, dst_ts);
charon->kernel->acquire(charon->kernel, reqid, &data);
data.src->destroy(data.src);
data.dst->destroy(data.dst);
}
}
/**

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -24,7 +24,7 @@
typedef struct acquire_job_t acquire_job_t;
#include <library.h>
#include <selectors/traffic_selector.h>
#include <kernel/kernel_interface.h>
#include <processing/jobs/job.h>
/**
@ -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_ @}*/

View File

@ -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)

View File

@ -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.