aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/conftest/actions.c14
-rw-r--r--src/frontends/android/jni/libandroidbridge/kernel/android_ipsec.c6
-rw-r--r--src/libcharon/kernel/kernel_handler.c12
-rw-r--r--src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c6
-rw-r--r--src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c11
-rw-r--r--src/libcharon/plugins/stroke/stroke_control.c6
-rw-r--r--src/libcharon/processing/jobs/delete_child_sa_job.c26
-rw-r--r--src/libcharon/processing/jobs/delete_child_sa_job.h9
-rw-r--r--src/libcharon/processing/jobs/rekey_child_sa_job.c27
-rw-r--r--src/libcharon/processing/jobs/rekey_child_sa_job.h10
-rw-r--r--src/libcharon/sa/ikev2/tasks/child_rekey.c4
-rw-r--r--src/libhydra/kernel/kernel_interface.c7
-rw-r--r--src/libhydra/kernel/kernel_interface.h6
-rw-r--r--src/libhydra/kernel/kernel_listener.h6
-rw-r--r--src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c19
-rw-r--r--src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c19
-rw-r--r--src/libipsec/ipsec_event_listener.h6
-rw-r--r--src/libipsec/ipsec_event_relay.c34
-rw-r--r--src/libipsec/ipsec_event_relay.h6
-rw-r--r--src/libipsec/ipsec_sa.c8
20 files changed, 124 insertions, 118 deletions
diff --git a/src/conftest/actions.c b/src/conftest/actions.c
index 3f937b118..474672ca1 100644
--- a/src/conftest/actions.c
+++ b/src/conftest/actions.c
@@ -117,19 +117,20 @@ static job_requeue_t rekey_child(char *config)
enumerator_t *enumerator, *children;
ike_sa_t *ike_sa;
child_sa_t *child_sa;
- u_int32_t reqid = 0, spi = 0;
- protocol_id_t proto = PROTO_ESP;
+ u_int32_t spi, proto;
+ host_t *dst = NULL;
enumerator = charon->controller->create_ike_sa_enumerator(
charon->controller, TRUE);
while (enumerator->enumerate(enumerator, &ike_sa))
{
children = ike_sa->create_child_sa_enumerator(ike_sa);
- while (children->enumerate(children, (void**)&child_sa))
+ while (children->enumerate(children, &child_sa))
{
if (streq(config, child_sa->get_name(child_sa)))
{
- reqid = child_sa->get_reqid(child_sa);
+ dst = ike_sa->get_my_host(ike_sa);
+ dst = dst->clone(dst);
proto = child_sa->get_protocol(child_sa);
spi = child_sa->get_spi(child_sa, TRUE);
break;
@@ -138,11 +139,12 @@ static job_requeue_t rekey_child(char *config)
children->destroy(children);
}
enumerator->destroy(enumerator);
- if (reqid)
+ if (dst)
{
DBG1(DBG_CFG, "starting rekey of CHILD_SA '%s'", config);
lib->processor->queue_job(lib->processor,
- (job_t*)rekey_child_sa_job_create(reqid, proto, spi));
+ (job_t*)rekey_child_sa_job_create(proto, spi, dst));
+ dst->destroy(dst);
}
else
{
diff --git a/src/frontends/android/jni/libandroidbridge/kernel/android_ipsec.c b/src/frontends/android/jni/libandroidbridge/kernel/android_ipsec.c
index 65166077e..a0aefaa4e 100644
--- a/src/frontends/android/jni/libandroidbridge/kernel/android_ipsec.c
+++ b/src/frontends/android/jni/libandroidbridge/kernel/android_ipsec.c
@@ -40,10 +40,10 @@ struct private_kernel_android_ipsec_t {
/**
* Callback registrered with libipsec.
*/
-void expire(u_int32_t reqid, u_int8_t protocol, u_int32_t spi, bool hard)
+static void expire(u_int8_t protocol, u_int32_t spi, host_t *dst, bool hard)
{
- hydra->kernel_interface->expire(hydra->kernel_interface, reqid, protocol,
- spi, hard);
+ hydra->kernel_interface->expire(hydra->kernel_interface, protocol,
+ spi, dst, hard);
}
METHOD(kernel_ipsec_t, get_spi, status_t,
diff --git a/src/libcharon/kernel/kernel_handler.c b/src/libcharon/kernel/kernel_handler.c
index 059124e35..a6656e7d5 100644
--- a/src/libcharon/kernel/kernel_handler.c
+++ b/src/libcharon/kernel/kernel_handler.c
@@ -72,23 +72,23 @@ METHOD(kernel_listener_t, acquire, bool,
}
METHOD(kernel_listener_t, expire, bool,
- private_kernel_handler_t *this, u_int32_t reqid, u_int8_t protocol,
- u_int32_t spi, bool hard)
+ private_kernel_handler_t *this, u_int8_t protocol, u_int32_t spi,
+ host_t *dst, bool hard)
{
protocol_id_t proto = proto_ip2ike(protocol);
- DBG1(DBG_KNL, "creating %s job for %N CHILD_SA with SPI %.8x and reqid {%u}",
- hard ? "delete" : "rekey", protocol_id_names, proto, ntohl(spi), reqid);
+ DBG1(DBG_KNL, "creating %s job for CHILD_SA %N/0x%08x/%H",
+ hard ? "delete" : "rekey", protocol_id_names, proto, ntohl(spi), dst);
if (hard)
{
lib->processor->queue_job(lib->processor,
- (job_t*)delete_child_sa_job_create(reqid, proto, spi, hard));
+ (job_t*)delete_child_sa_job_create(proto, spi, dst, hard));
}
else
{
lib->processor->queue_job(lib->processor,
- (job_t*)rekey_child_sa_job_create(reqid, proto, spi));
+ (job_t*)rekey_child_sa_job_create(proto, spi, dst));
}
return TRUE;
}
diff --git a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c
index 362b32746..e6c5d6a1d 100644
--- a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c
+++ b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c
@@ -222,10 +222,10 @@ static inline bool policy_entry_equals(policy_entry_t *a,
/**
* Expiration callback
*/
-static void expire(u_int32_t reqid, u_int8_t protocol, u_int32_t spi, bool hard)
+static void expire(u_int8_t protocol, u_int32_t spi, host_t *dst, bool hard)
{
- hydra->kernel_interface->expire(hydra->kernel_interface, reqid, protocol,
- spi, hard);
+ hydra->kernel_interface->expire(hydra->kernel_interface, protocol,
+ spi, dst, hard);
}
METHOD(kernel_ipsec_t, get_features, kernel_feature_t,
diff --git a/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c b/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c
index 9fd6541a5..86db9e643 100644
--- a/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c
+++ b/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c
@@ -2032,9 +2032,8 @@ static void expire_data_destroy(expire_data_t *data)
static job_requeue_t expire_job(expire_data_t *data)
{
private_kernel_wfp_ipsec_t *this = data->this;
- u_int32_t reqid = 0;
u_int8_t protocol;
- entry_t *entry;
+ entry_t *entry = NULL;
sa_entry_t key = {
.spi = data->spi,
.dst = data->dst,
@@ -2048,7 +2047,6 @@ static job_requeue_t expire_job(expire_data_t *data)
if (entry)
{
protocol = entry->isa.protocol;
- reqid = entry->reqid;
if (entry->osa.dst)
{
key.dst = entry->osa.dst;
@@ -2065,15 +2063,14 @@ static job_requeue_t expire_job(expire_data_t *data)
if (entry)
{
protocol = entry->isa.protocol;
- reqid = entry->reqid;
}
this->mutex->unlock(this->mutex);
}
- if (reqid)
+ if (entry)
{
- hydra->kernel_interface->expire(hydra->kernel_interface,
- reqid, protocol, data->spi, data->hard);
+ hydra->kernel_interface->expire(hydra->kernel_interface, protocol,
+ data->spi, data->dst, data->hard);
}
return JOB_REQUEUE_NONE;
diff --git a/src/libcharon/plugins/stroke/stroke_control.c b/src/libcharon/plugins/stroke/stroke_control.c
index 99d07f593..0084fbf93 100644
--- a/src/libcharon/plugins/stroke/stroke_control.c
+++ b/src/libcharon/plugins/stroke/stroke_control.c
@@ -432,13 +432,13 @@ METHOD(stroke_control_t, rekey, void,
while (children->enumerate(children, (void**)&child_sa))
{
if ((name && streq(name, child_sa->get_name(child_sa))) ||
- (id && id == child_sa->get_reqid(child_sa)))
+ (id && id == child_sa->get_unique_id(child_sa)))
{
lib->processor->queue_job(lib->processor,
(job_t*)rekey_child_sa_job_create(
- child_sa->get_reqid(child_sa),
child_sa->get_protocol(child_sa),
- child_sa->get_spi(child_sa, TRUE)));
+ child_sa->get_spi(child_sa, TRUE),
+ ike_sa->get_my_host(ike_sa)));
if (!all)
{
finished = TRUE;
diff --git a/src/libcharon/processing/jobs/delete_child_sa_job.c b/src/libcharon/processing/jobs/delete_child_sa_job.c
index 9afbac02b..0d85883be 100644
--- a/src/libcharon/processing/jobs/delete_child_sa_job.c
+++ b/src/libcharon/processing/jobs/delete_child_sa_job.c
@@ -31,11 +31,6 @@ struct private_delete_child_sa_job_t {
delete_child_sa_job_t public;
/**
- * reqid of the CHILD_SA
- */
- u_int32_t reqid;
-
- /**
* protocol of the CHILD_SA (ESP/AH)
*/
protocol_id_t protocol;
@@ -46,6 +41,11 @@ struct private_delete_child_sa_job_t {
u_int32_t spi;
/**
+ * SA destination address
+ */
+ host_t *dst;
+
+ /**
* Delete for an expired CHILD_SA
*/
bool expired;
@@ -54,6 +54,7 @@ struct private_delete_child_sa_job_t {
METHOD(job_t, destroy, void,
private_delete_child_sa_job_t *this)
{
+ this->dst->destroy(this->dst);
free(this);
}
@@ -62,12 +63,12 @@ METHOD(job_t, execute, job_requeue_t,
{
ike_sa_t *ike_sa;
- ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
- this->reqid, TRUE);
+ ike_sa = charon->child_sa_manager->checkout(charon->child_sa_manager,
+ this->protocol, this->spi, this->dst, NULL);
if (ike_sa == NULL)
{
- DBG1(DBG_JOB, "CHILD_SA with reqid %d not found for delete",
- this->reqid);
+ DBG1(DBG_JOB, "CHILD_SA %N/0x%08x/%H not found for delete",
+ protocol_id_names, this->protocol, htonl(this->spi), this->dst);
}
else
{
@@ -87,8 +88,8 @@ METHOD(job_t, get_priority, job_priority_t,
/*
* Described in header
*/
-delete_child_sa_job_t *delete_child_sa_job_create(u_int32_t reqid,
- protocol_id_t protocol, u_int32_t spi, bool expired)
+delete_child_sa_job_t *delete_child_sa_job_create(protocol_id_t protocol,
+ u_int32_t spi, host_t *dst, bool expired)
{
private_delete_child_sa_job_t *this;
@@ -100,12 +101,11 @@ delete_child_sa_job_t *delete_child_sa_job_create(u_int32_t reqid,
.destroy = _destroy,
},
},
- .reqid = reqid,
.protocol = protocol,
.spi = spi,
+ .dst = dst->clone(dst),
.expired = expired,
);
return &this->public;
}
-
diff --git a/src/libcharon/processing/jobs/delete_child_sa_job.h b/src/libcharon/processing/jobs/delete_child_sa_job.h
index be6d578bc..6fa53644c 100644
--- a/src/libcharon/processing/jobs/delete_child_sa_job.h
+++ b/src/libcharon/processing/jobs/delete_child_sa_job.h
@@ -44,16 +44,13 @@ struct delete_child_sa_job_t {
/**
* Creates a job of type DELETE_CHILD_SA.
*
- * The CHILD_SA is identified by its reqid, protocol (AH/ESP) and its
- * inbound SPI.
- *
- * @param reqid reqid of the CHILD_SA, as used in kernel
* @param protocol protocol of the CHILD_SA
* @param spi security parameter index of the CHILD_SA
+ * @param dst SA destination address
* @param expired TRUE if CHILD_SA already expired
* @return delete_child_sa_job_t object
*/
-delete_child_sa_job_t *delete_child_sa_job_create(u_int32_t reqid,
- protocol_id_t protocol, u_int32_t spi, bool expired);
+delete_child_sa_job_t *delete_child_sa_job_create(protocol_id_t protocol,
+ u_int32_t spi, host_t *dst, bool expired);
#endif /** DELETE_CHILD_SA_JOB_H_ @}*/
diff --git a/src/libcharon/processing/jobs/rekey_child_sa_job.c b/src/libcharon/processing/jobs/rekey_child_sa_job.c
index 1bf8dc0cb..8f17d39ab 100644
--- a/src/libcharon/processing/jobs/rekey_child_sa_job.c
+++ b/src/libcharon/processing/jobs/rekey_child_sa_job.c
@@ -24,17 +24,13 @@ typedef struct private_rekey_child_sa_job_t private_rekey_child_sa_job_t;
* Private data of an rekey_child_sa_job_t object.
*/
struct private_rekey_child_sa_job_t {
+
/**
* Public rekey_child_sa_job_t interface.
*/
rekey_child_sa_job_t public;
/**
- * reqid of the child to rekey
- */
- u_int32_t reqid;
-
- /**
* protocol of the CHILD_SA (ESP/AH)
*/
protocol_id_t protocol;
@@ -43,11 +39,17 @@ struct private_rekey_child_sa_job_t {
* inbound SPI of the CHILD_SA
*/
u_int32_t spi;
+
+ /**
+ * SA destination address
+ */
+ host_t *dst;
};
METHOD(job_t, destroy, void,
private_rekey_child_sa_job_t *this)
{
+ this->dst->destroy(this->dst);
free(this);
}
@@ -56,12 +58,12 @@ METHOD(job_t, execute, job_requeue_t,
{
ike_sa_t *ike_sa;
- ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
- this->reqid, TRUE);
+ ike_sa = charon->child_sa_manager->checkout(charon->child_sa_manager,
+ this->protocol, this->spi, this->dst, NULL);
if (ike_sa == NULL)
{
- DBG2(DBG_JOB, "CHILD_SA with reqid %d not found for rekeying",
- this->reqid);
+ DBG1(DBG_JOB, "CHILD_SA %N/0x%08x/%H not found for rekey",
+ protocol_id_names, this->protocol, htonl(this->spi), this->dst);
}
else
{
@@ -80,9 +82,8 @@ METHOD(job_t, get_priority, job_priority_t,
/*
* Described in header
*/
-rekey_child_sa_job_t *rekey_child_sa_job_create(u_int32_t reqid,
- protocol_id_t protocol,
- u_int32_t spi)
+rekey_child_sa_job_t *rekey_child_sa_job_create(protocol_id_t protocol,
+ u_int32_t spi, host_t *dst)
{
private_rekey_child_sa_job_t *this;
@@ -94,9 +95,9 @@ rekey_child_sa_job_t *rekey_child_sa_job_create(u_int32_t reqid,
.destroy = _destroy,
},
},
- .reqid = reqid,
.protocol = protocol,
.spi = spi,
+ .dst = dst->clone(dst),
);
return &this->public;
diff --git a/src/libcharon/processing/jobs/rekey_child_sa_job.h b/src/libcharon/processing/jobs/rekey_child_sa_job.h
index fcbe65a06..364bb5ae7 100644
--- a/src/libcharon/processing/jobs/rekey_child_sa_job.h
+++ b/src/libcharon/processing/jobs/rekey_child_sa_job.h
@@ -43,15 +43,11 @@ struct rekey_child_sa_job_t {
/**
* Creates a job of type REKEY_CHILD_SA.
*
- * The CHILD_SA is identified by its protocol (AH/ESP) and its
- * inbound SPI.
- *
- * @param reqid reqid of the CHILD_SA to rekey
* @param protocol protocol of the CHILD_SA
* @param spi security parameter index of the CHILD_SA
+ * @param dst SA destination address
* @return rekey_child_sa_job_t object
*/
-rekey_child_sa_job_t *rekey_child_sa_job_create(u_int32_t reqid,
- protocol_id_t protocol,
- u_int32_t spi);
+rekey_child_sa_job_t *rekey_child_sa_job_create(protocol_id_t protocol,
+ u_int32_t spi, host_t *dst);
#endif /** REKEY_CHILD_SA_JOB_H_ @}*/
diff --git a/src/libcharon/sa/ikev2/tasks/child_rekey.c b/src/libcharon/sa/ikev2/tasks/child_rekey.c
index 213155a29..c806e19ca 100644
--- a/src/libcharon/sa/ikev2/tasks/child_rekey.c
+++ b/src/libcharon/sa/ikev2/tasks/child_rekey.c
@@ -96,9 +96,9 @@ static void schedule_delayed_rekey(private_child_rekey_t *this)
retry = RETRY_INTERVAL - (random() % RETRY_JITTER);
job = (job_t*)rekey_child_sa_job_create(
- this->child_sa->get_reqid(this->child_sa),
this->child_sa->get_protocol(this->child_sa),
- this->child_sa->get_spi(this->child_sa, TRUE));
+ this->child_sa->get_spi(this->child_sa, TRUE),
+ this->ike_sa->get_my_host(this->ike_sa));
DBG1(DBG_IKE, "CHILD_SA rekeying failed, trying again in %d seconds", retry);
this->child_sa->set_state(this->child_sa, CHILD_INSTALLED);
lib->scheduler->schedule_job(lib->scheduler, job, retry);
diff --git a/src/libhydra/kernel/kernel_interface.c b/src/libhydra/kernel/kernel_interface.c
index 28821fc15..b5ade37d1 100644
--- a/src/libhydra/kernel/kernel_interface.c
+++ b/src/libhydra/kernel/kernel_interface.c
@@ -815,17 +815,18 @@ METHOD(kernel_interface_t, acquire, void,
}
METHOD(kernel_interface_t, expire, void,
- private_kernel_interface_t *this, u_int32_t reqid, u_int8_t protocol,
- u_int32_t spi, bool hard)
+ private_kernel_interface_t *this, u_int8_t protocol, u_int32_t spi,
+ host_t *dst, bool hard)
{
kernel_listener_t *listener;
enumerator_t *enumerator;
+
this->mutex->lock(this->mutex);
enumerator = this->listeners->create_enumerator(this->listeners);
while (enumerator->enumerate(enumerator, &listener))
{
if (listener->expire &&
- !listener->expire(listener, reqid, protocol, spi, hard))
+ !listener->expire(listener, protocol, spi, dst, hard))
{
this->listeners->remove_at(this->listeners, enumerator);
}
diff --git a/src/libhydra/kernel/kernel_interface.h b/src/libhydra/kernel/kernel_interface.h
index 9a86e78d6..2db53f504 100644
--- a/src/libhydra/kernel/kernel_interface.h
+++ b/src/libhydra/kernel/kernel_interface.h
@@ -559,13 +559,13 @@ struct kernel_interface_t {
/**
* Raise an expire event.
*
- * @param reqid reqid of the expired SA
* @param protocol protocol of the expired SA
* @param spi spi of the expired SA
+ * @param dst destination address of expired SA
* @param hard TRUE if it is a hard expire, FALSE otherwise
*/
- void (*expire)(kernel_interface_t *this, u_int32_t reqid,
- u_int8_t protocol, u_int32_t spi, bool hard);
+ void (*expire)(kernel_interface_t *this, u_int8_t protocol, u_int32_t spi,
+ host_t *dst, bool hard);
/**
* Raise a mapping event.
diff --git a/src/libhydra/kernel/kernel_listener.h b/src/libhydra/kernel/kernel_listener.h
index 4382a43fd..122453f72 100644
--- a/src/libhydra/kernel/kernel_listener.h
+++ b/src/libhydra/kernel/kernel_listener.h
@@ -49,14 +49,14 @@ struct kernel_listener_t {
/**
* Hook called if an exire event for an IPsec SA is received.
*
- * @param reqid reqid of the expired SA
* @param protocol protocol of the expired SA
* @param spi spi of the expired SA
+ * @param dst destination address of expired SA
* @param hard TRUE if it is a hard expire, FALSE otherwise
* @return TRUE to remain registered, FALSE to unregister
*/
- bool (*expire)(kernel_listener_t *this, u_int32_t reqid,
- u_int8_t protocol, u_int32_t spi, bool hard);
+ bool (*expire)(kernel_listener_t *this, u_int8_t protocol, u_int32_t spi,
+ host_t *dst, bool hard);
/**
* Hook called if the NAT mappings of an IPsec SA changed.
diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
index 31bb4f656..f8077d836 100644
--- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
+++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
@@ -870,25 +870,26 @@ static void process_expire(private_kernel_netlink_ipsec_t *this,
struct nlmsghdr *hdr)
{
struct xfrm_user_expire *expire;
- u_int32_t spi, reqid;
+ u_int32_t spi;
u_int8_t protocol;
+ host_t *dst;
expire = NLMSG_DATA(hdr);
protocol = expire->state.id.proto;
spi = expire->state.id.spi;
- reqid = expire->state.reqid;
DBG2(DBG_KNL, "received a XFRM_MSG_EXPIRE");
- if (protocol != IPPROTO_ESP && protocol != IPPROTO_AH)
+ if (protocol == IPPROTO_ESP || protocol == IPPROTO_AH)
{
- DBG2(DBG_KNL, "ignoring XFRM_MSG_EXPIRE for SA with SPI %.8x and "
- "reqid {%u} which is not a CHILD_SA", ntohl(spi), reqid);
- return;
+ dst = xfrm2host(expire->state.family, &expire->state.id.daddr, 0);
+ if (dst)
+ {
+ hydra->kernel_interface->expire(hydra->kernel_interface, protocol,
+ spi, dst, expire->hard != 0);
+ dst->destroy(dst);
+ }
}
-
- hydra->kernel_interface->expire(hydra->kernel_interface, reqid, protocol,
- spi, expire->hard != 0);
}
/**
diff --git a/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
index 348549bfa..9b846864e 100644
--- a/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
+++ b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
@@ -1296,7 +1296,8 @@ static void process_expire(private_kernel_pfkey_ipsec_t *this,
{
pfkey_msg_t response;
u_int8_t protocol;
- u_int32_t spi, reqid;
+ u_int32_t spi;
+ host_t *dst;
bool hard;
DBG2(DBG_KNL, "received an SADB_EXPIRE");
@@ -1309,18 +1310,18 @@ static void process_expire(private_kernel_pfkey_ipsec_t *this,
protocol = satype2proto(msg->sadb_msg_satype);
spi = response.sa->sadb_sa_spi;
- reqid = response.x_sa2->sadb_x_sa2_reqid;
hard = response.lft_hard != NULL;
- if (protocol != IPPROTO_ESP && protocol != IPPROTO_AH)
+ if (protocol == IPPROTO_ESP || protocol == IPPROTO_AH)
{
- DBG2(DBG_KNL, "ignoring SADB_EXPIRE for SA with SPI %.8x and "
- "reqid {%u} which is not a CHILD_SA", ntohl(spi), reqid);
- return;
+ dst = host_create_from_sockaddr((sockaddr_t*)(response.dst + 1));
+ if (dst)
+ {
+ hydra->kernel_interface->expire(hydra->kernel_interface, protocol,
+ spi, dst, hard);
+ dst->destroy(dst);
+ }
}
-
- hydra->kernel_interface->expire(hydra->kernel_interface, reqid, protocol,
- spi, hard);
}
#ifdef SADB_X_MIGRATE
diff --git a/src/libipsec/ipsec_event_listener.h b/src/libipsec/ipsec_event_listener.h
index c5c39b0f1..f15f6fe52 100644
--- a/src/libipsec/ipsec_event_listener.h
+++ b/src/libipsec/ipsec_event_listener.h
@@ -35,14 +35,12 @@ struct ipsec_event_listener_t {
/**
* Called when the lifetime of an IPsec SA expired
*
- * @param reqid reqid of the expired SA
* @param protocol protocol of the expired SA
* @param spi spi of the expired SA
+ * @param dst destination address of expired SA
* @param hard TRUE if this is a hard expire, FALSE otherwise
*/
- void (*expire)(u_int32_t reqid, u_int8_t protocol, u_int32_t spi,
- bool hard);
-
+ void (*expire)(u_int8_t protocol, u_int32_t spi, host_t *dst, bool hard);
};
#endif /** IPSEC_EVENT_LISTENER_H_ @}*/
diff --git a/src/libipsec/ipsec_event_relay.c b/src/libipsec/ipsec_event_relay.c
index c6b2a550d..048063053 100644
--- a/src/libipsec/ipsec_event_relay.c
+++ b/src/libipsec/ipsec_event_relay.c
@@ -65,9 +65,9 @@ typedef struct {
} type;
/**
- * Reqid of the SA, if any
+ * Protocol of the SA
*/
- u_int32_t reqid;
+ u_int8_t protocol;
/**
* SPI of the SA, if any
@@ -75,13 +75,16 @@ typedef struct {
u_int32_t spi;
/**
+ * SA destination address
+ */
+ host_t *dst;
+
+ /**
* Additional data for specific event types
*/
union {
struct {
- /** Protocol of the SA */
- u_int8_t protocol;
/** TRUE in case of a hard expire */
bool hard;
} expire;
@@ -91,6 +94,15 @@ typedef struct {
} ipsec_event_t;
/**
+ * Destroy IPsec event data
+ */
+static void ipsec_event_destroy(ipsec_event_t *event)
+{
+ event->dst->destroy(event->dst);
+ free(event);
+}
+
+/**
* Dequeue events and relay them to listeners
*/
static job_requeue_t handle_events(private_ipsec_event_relay_t *this)
@@ -110,31 +122,31 @@ static job_requeue_t handle_events(private_ipsec_event_relay_t *this)
case IPSEC_EVENT_EXPIRE:
if (current->expire)
{
- current->expire(event->reqid, event->data.expire.protocol,
- event->spi, event->data.expire.hard);
+ current->expire(event->protocol, event->spi, event->dst,
+ event->data.expire.hard);
}
break;
}
}
enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
- free(event);
+ ipsec_event_destroy(event);
return JOB_REQUEUE_DIRECT;
}
METHOD(ipsec_event_relay_t, expire, void,
- private_ipsec_event_relay_t *this, u_int32_t reqid, u_int8_t protocol,
- u_int32_t spi, bool hard)
+ private_ipsec_event_relay_t *this, u_int8_t protocol, u_int32_t spi,
+ host_t *dst, bool hard)
{
ipsec_event_t *event;
INIT(event,
.type = IPSEC_EVENT_EXPIRE,
- .reqid = reqid,
+ .protocol = protocol,
.spi = spi,
+ .dst = dst->clone(dst),
.data = {
.expire = {
- .protocol = protocol,
.hard = hard,
},
},
diff --git a/src/libipsec/ipsec_event_relay.h b/src/libipsec/ipsec_event_relay.h
index c6935d546..1dddf121b 100644
--- a/src/libipsec/ipsec_event_relay.h
+++ b/src/libipsec/ipsec_event_relay.h
@@ -38,13 +38,13 @@ struct ipsec_event_relay_t {
/**
* Raise an expire event.
*
- * @param reqid reqid of the expired IPsec SA
* @param protocol protocol (e.g ESP) of the expired SA
* @param spi SPI of the expired SA
+ * @param dst destination address of expired SA
* @param hard TRUE for a hard expire, FALSE otherwise
*/
- void (*expire)(ipsec_event_relay_t *this, u_int32_t reqid,
- u_int8_t protocol, u_int32_t spi, bool hard);
+ void (*expire)(ipsec_event_relay_t *this, u_int8_t protocol, u_int32_t spi,
+ host_t *dst, bool hard);
/**
* Register a listener to events raised by this manager
diff --git a/src/libipsec/ipsec_sa.c b/src/libipsec/ipsec_sa.c
index 3d0bbe169..ccbbb1b3c 100644
--- a/src/libipsec/ipsec_sa.c
+++ b/src/libipsec/ipsec_sa.c
@@ -194,8 +194,8 @@ METHOD(ipsec_sa_t, expire, void,
if (!this->hard_expired)
{
this->hard_expired = TRUE;
- ipsec->events->expire(ipsec->events, this->reqid, this->protocol,
- this->spi, TRUE);
+ ipsec->events->expire(ipsec->events, this->protocol, this->spi,
+ this->dst, TRUE);
}
}
else
@@ -203,8 +203,8 @@ METHOD(ipsec_sa_t, expire, void,
if (!this->hard_expired && !this->soft_expired)
{
this->soft_expired = TRUE;
- ipsec->events->expire(ipsec->events, this->reqid, this->protocol,
- this->spi, FALSE);
+ ipsec->events->expire(ipsec->events, this->protocol, this->spi,
+ this->dst, FALSE);
}
}
}