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

This commit is contained in:
Tobias Brunner
2022-04-14 18:42:01 +02:00
parent 9983326b20
commit 3b699c720f
12 changed files with 81 additions and 63 deletions
+3 -1
View File
@@ -24,8 +24,10 @@
void charon_esa_acquire(result_type *res, const sp_id_type sp_id) 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); 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; *res = TKM_OK;
} }
+4 -5
View File
@@ -53,20 +53,19 @@ static inline protocol_id_t proto_ip2ike(uint8_t protocol)
} }
METHOD(kernel_listener_t, acquire, bool, METHOD(kernel_listener_t, acquire, bool,
private_kernel_handler_t *this, uint32_t reqid, private_kernel_handler_t *this, uint32_t reqid, kernel_acquire_data_t *data)
traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
{ {
if (src_ts && dst_ts) if (data->src && data->dst)
{ {
DBG1(DBG_KNL, "creating acquire job for policy %R === %R with " 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 else
{ {
DBG1(DBG_KNL, "creating acquire job for policy with reqid {%u}", reqid); DBG1(DBG_KNL, "creating acquire job for policy with reqid {%u}", reqid);
} }
lib->processor->queue_job(lib->processor, 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; return TRUE;
} }
+2 -3
View File
@@ -827,7 +827,7 @@ METHOD(kernel_interface_t, remove_listener, void,
METHOD(kernel_interface_t, acquire, void, METHOD(kernel_interface_t, acquire, void,
private_kernel_interface_t *this, uint32_t reqid, 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; kernel_listener_t *listener;
enumerator_t *enumerator; enumerator_t *enumerator;
@@ -835,8 +835,7 @@ METHOD(kernel_interface_t, acquire, void,
enumerator = this->listeners->create_enumerator(this->listeners); enumerator = this->listeners->create_enumerator(this->listeners);
while (enumerator->enumerate(enumerator, &listener)) while (enumerator->enumerate(enumerator, &listener))
{ {
if (listener->acquire && if (listener->acquire && !listener->acquire(listener, reqid, data))
!listener->acquire(listener, reqid, src_ts, dst_ts))
{ {
this->listeners->remove_at(this->listeners, enumerator); this->listeners->remove_at(this->listeners, enumerator);
} }
+2 -3
View File
@@ -513,11 +513,10 @@ struct kernel_interface_t {
* Raise an acquire event. * Raise an acquire event.
* *
* @param reqid reqid of the policy to acquire * @param reqid reqid of the policy to acquire
* @param src_ts source traffic selector * @param data data from the acquire
* @param dst_ts destination traffic selector
*/ */
void (*acquire)(kernel_interface_t *this, uint32_t reqid, 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. * Raise an expire event.
+13 -3
View File
@@ -22,12 +22,23 @@
#define KERNEL_LISTENER_H_ #define KERNEL_LISTENER_H_
typedef struct kernel_listener_t kernel_listener_t; typedef struct kernel_listener_t kernel_listener_t;
typedef struct kernel_acquire_data_t kernel_acquire_data_t;
#include <networking/host.h> #include <networking/host.h>
#include <networking/tun_device.h> #include <networking/tun_device.h>
#include <selectors/traffic_selector.h> #include <selectors/traffic_selector.h>
#include <kernel/kernel_ipsec.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. * 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. * Hook called if an acquire event for a policy is received.
* *
* @param reqid reqid of the policy to acquire * @param reqid reqid of the policy to acquire
* @param src_ts source traffic selector * @param data data from the acquire
* @param dst_ts destination traffic selector
* @return TRUE to remain registered, FALSE to unregister * @return TRUE to remain registered, FALSE to unregister
*/ */
bool (*acquire)(kernel_listener_t *this, uint32_t reqid, 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. * Hook called if an expire event for an IPsec SA is received.
@@ -897,7 +897,7 @@ static void process_acquire(private_kernel_netlink_ipsec_t *this,
struct xfrm_user_acquire *acquire; struct xfrm_user_acquire *acquire;
struct rtattr *rta; struct rtattr *rta;
size_t rtasize; size_t rtasize;
traffic_selector_t *src_ts, *dst_ts; kernel_acquire_data_t data = {};
uint32_t reqid = 0; uint32_t reqid = 0;
uint8_t proto; 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 */ /* acquire for AH/ESP only, not for IPCOMP */
return; return;
} }
src_ts = selector2ts(&acquire->sel, TRUE); data.src = selector2ts(&acquire->sel, TRUE);
dst_ts = selector2ts(&acquire->sel, FALSE); 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);
} }
/** /**
@@ -1318,8 +1318,8 @@ static void process_acquire(private_kernel_pfkey_ipsec_t *this,
struct sadb_msg* msg) struct sadb_msg* msg)
{ {
pfkey_msg_t response; pfkey_msg_t response;
kernel_acquire_data_t data = {};
uint32_t index, reqid = 0; uint32_t index, reqid = 0;
traffic_selector_t *src_ts, *dst_ts;
policy_entry_t *policy; policy_entry_t *policy;
policy_sa_t *sa; policy_sa_t *sa;
@@ -1363,10 +1363,16 @@ static void process_acquire(private_kernel_pfkey_ipsec_t *this,
this->mutex->unlock(this->mutex); this->mutex->unlock(this->mutex);
} }
src_ts = sadb_address2ts(response.src); if (reqid)
dst_ts = sadb_address2ts(response.dst); {
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);
}
} }
/** /**
@@ -1634,6 +1634,7 @@ static u_int hash_trap(trap_t *trap)
static void acquire(private_kernel_wfp_ipsec_t *this, UINT64 filter_id, static void acquire(private_kernel_wfp_ipsec_t *this, UINT64 filter_id,
traffic_selector_t *src, traffic_selector_t *dst) traffic_selector_t *src, traffic_selector_t *dst)
{ {
kernel_acquire_data_t data = {};
uint32_t reqid = 0; uint32_t reqid = 0;
trap_t *trap, key = { trap_t *trap, key = {
.filter_id = filter_id, .filter_id = filter_id,
@@ -1649,9 +1650,13 @@ static void acquire(private_kernel_wfp_ipsec_t *this, UINT64 filter_id,
if (reqid) if (reqid)
{ {
src = src ? src->clone(src) : NULL; data.src = src ? src->clone(src) : NULL;
dst = dst ? dst->clone(dst) : NULL; data.dst = dst ? dst->clone(dst) : NULL;
charon->kernel->acquire(charon->kernel, reqid, src, dst);
charon->kernel->acquire(charon->kernel, reqid, &data);
DESTROY_IF(data.src);
DESTROY_IF(data.dst);
} }
} }
+17 -17
View File
@@ -30,34 +30,28 @@ struct private_acquire_job_t {
acquire_job_t public; acquire_job_t public;
/** /**
* reqid of the child to rekey * reqid of the triggered policy
*/ */
uint32_t reqid; uint32_t reqid;
/** /**
* acquired source traffic selector * Data from the acquire
*/ */
traffic_selector_t *src_ts; kernel_acquire_data_t data;
/**
* acquired destination traffic selector
*/
traffic_selector_t *dst_ts;
}; };
METHOD(job_t, destroy, void, METHOD(job_t, destroy, void,
private_acquire_job_t *this) private_acquire_job_t *this)
{ {
DESTROY_IF(this->src_ts); DESTROY_IF(this->data.src);
DESTROY_IF(this->dst_ts); DESTROY_IF(this->data.dst);
free(this); free(this);
} }
METHOD(job_t, execute, job_requeue_t, METHOD(job_t, execute, job_requeue_t,
private_acquire_job_t *this) private_acquire_job_t *this)
{ {
charon->traps->acquire(charon->traps, this->reqid, charon->traps->acquire(charon->traps, this->reqid, &this->data);
this->src_ts, this->dst_ts);
return JOB_REQUEUE_NONE; return JOB_REQUEUE_NONE;
} }
@@ -70,9 +64,7 @@ METHOD(job_t, get_priority, job_priority_t,
/* /*
* Described in header * Described in header
*/ */
acquire_job_t *acquire_job_create(uint32_t reqid, acquire_job_t *acquire_job_create(uint32_t reqid, kernel_acquire_data_t *data)
traffic_selector_t *src_ts,
traffic_selector_t *dst_ts)
{ {
private_acquire_job_t *this; private_acquire_job_t *this;
@@ -85,10 +77,18 @@ acquire_job_t *acquire_job_create(uint32_t reqid,
}, },
}, },
.reqid = reqid, .reqid = reqid,
.src_ts = src_ts, .data = *data,
.dst_ts = dst_ts,
); );
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; return &this->public;
} }
+4 -7
View File
@@ -24,7 +24,7 @@
typedef struct acquire_job_t acquire_job_t; typedef struct acquire_job_t acquire_job_t;
#include <library.h> #include <library.h>
#include <selectors/traffic_selector.h> #include <kernel/kernel_interface.h>
#include <processing/jobs/job.h> #include <processing/jobs/job.h>
/** /**
@@ -42,13 +42,10 @@ struct acquire_job_t {
/** /**
* Creates a job of type ACQUIRE. * Creates a job of type ACQUIRE.
* *
* @param reqid reqid of the trapped CHILD_SA to acquire * @param reqid reqid of the triggered policy
* @param src_ts source traffic selector * @param data data from the acquire
* @param dst_ts destination traffic selector
* @return acquire_job_t object * @return acquire_job_t object
*/ */
acquire_job_t *acquire_job_create(uint32_t reqid, acquire_job_t *acquire_job_create(uint32_t reqid, kernel_acquire_data_t *data);
traffic_selector_t *src_ts,
traffic_selector_t *dst_ts);
#endif /** REKEY_CHILD_SA_JOB_H_ @}*/ #endif /** REKEY_CHILD_SA_JOB_H_ @}*/
+8 -9
View File
@@ -423,8 +423,7 @@ METHOD(trap_manager_t, create_enumerator, enumerator_t*,
} }
METHOD(trap_manager_t, acquire, void, METHOD(trap_manager_t, acquire, void,
private_trap_manager_t *this, uint32_t reqid, private_trap_manager_t *this, uint32_t reqid, kernel_acquire_data_t *data)
traffic_selector_t *src, traffic_selector_t *dst)
{ {
enumerator_t *enumerator; enumerator_t *enumerator;
entry_t *entry, *found = NULL; entry_t *entry, *found = NULL;
@@ -454,7 +453,6 @@ METHOD(trap_manager_t, acquire, void,
this->lock->unlock(this->lock); this->lock->unlock(this->lock);
return; return;
} }
reqid = found->child_sa->get_reqid(found->child_sa);
wildcard = found->wildcard; wildcard = found->wildcard;
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
@@ -463,7 +461,7 @@ METHOD(trap_manager_t, acquire, void,
* with the same peer */ * with the same peer */
uint8_t mask; 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, if (this->acquires->find_first(this->acquires, acquire_by_dst,
(void**)&acquire, host)) (void**)&acquire, host))
{ {
@@ -497,7 +495,8 @@ METHOD(trap_manager_t, acquire, void,
this->mutex->unlock(this->mutex); this->mutex->unlock(this->mutex);
if (ignore) 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); this->lock->unlock(this->lock);
return; return;
} }
@@ -521,12 +520,12 @@ METHOD(trap_manager_t, acquire, void,
ike_cfg = ike_sa->get_ike_cfg(ike_sa); ike_cfg = ike_sa->get_ike_cfg(ike_sa);
port = ike_cfg->get_other_port(ike_cfg); 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); host->set_port(host, port);
ike_sa->set_other_host(ike_sa, host); ike_sa->set_other_host(ike_sa, host);
port = ike_cfg->get_my_port(ike_cfg); 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); host->set_port(host, port);
ike_sa->set_my_host(ike_sa, host); ike_sa->set_my_host(ike_sa, host);
@@ -544,8 +543,8 @@ METHOD(trap_manager_t, acquire, void,
{ {
child_init_args_t args = { child_init_args_t args = {
.reqid = reqid, .reqid = reqid,
.src = src, .src = data->src,
.dst = dst, .dst = data->dst,
}; };
if (this->ignore_acquire_ts || ike_sa->get_version(ike_sa) == IKEV1) if (this->ignore_acquire_ts || ike_sa->get_version(ike_sa) == IKEV1)
+3 -4
View File
@@ -64,12 +64,11 @@ struct trap_manager_t {
/** /**
* Acquire an SA triggered by an installed trap. * Acquire an SA triggered by an installed trap.
* *
* @param reqid reqid of the triggering CHILD_SA * @param reqid reqid of the triggered policy
* @param src source of the triggering packet * @param data data from the acquire
* @param dst destination of the triggering packet
*/ */
void (*acquire)(trap_manager_t *this, uint32_t reqid, 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. * Clear any installed trap.