kernel-interface: Raise expires with a proto/SPI/dst tuple instead of reqid
This commit is contained in:
@@ -117,19 +117,20 @@ static job_requeue_t rekey_child(char *config)
|
|||||||
enumerator_t *enumerator, *children;
|
enumerator_t *enumerator, *children;
|
||||||
ike_sa_t *ike_sa;
|
ike_sa_t *ike_sa;
|
||||||
child_sa_t *child_sa;
|
child_sa_t *child_sa;
|
||||||
u_int32_t reqid = 0, spi = 0;
|
u_int32_t spi, proto;
|
||||||
protocol_id_t proto = PROTO_ESP;
|
host_t *dst = NULL;
|
||||||
|
|
||||||
enumerator = charon->controller->create_ike_sa_enumerator(
|
enumerator = charon->controller->create_ike_sa_enumerator(
|
||||||
charon->controller, TRUE);
|
charon->controller, TRUE);
|
||||||
while (enumerator->enumerate(enumerator, &ike_sa))
|
while (enumerator->enumerate(enumerator, &ike_sa))
|
||||||
{
|
{
|
||||||
children = ike_sa->create_child_sa_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)))
|
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);
|
proto = child_sa->get_protocol(child_sa);
|
||||||
spi = child_sa->get_spi(child_sa, TRUE);
|
spi = child_sa->get_spi(child_sa, TRUE);
|
||||||
break;
|
break;
|
||||||
@@ -138,11 +139,12 @@ static job_requeue_t rekey_child(char *config)
|
|||||||
children->destroy(children);
|
children->destroy(children);
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
if (reqid)
|
if (dst)
|
||||||
{
|
{
|
||||||
DBG1(DBG_CFG, "starting rekey of CHILD_SA '%s'", config);
|
DBG1(DBG_CFG, "starting rekey of CHILD_SA '%s'", config);
|
||||||
lib->processor->queue_job(lib->processor,
|
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
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -40,10 +40,10 @@ struct private_kernel_android_ipsec_t {
|
|||||||
/**
|
/**
|
||||||
* Callback registrered with libipsec.
|
* 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,
|
hydra->kernel_interface->expire(hydra->kernel_interface, protocol,
|
||||||
spi, hard);
|
spi, dst, hard);
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(kernel_ipsec_t, get_spi, status_t,
|
METHOD(kernel_ipsec_t, get_spi, status_t,
|
||||||
|
|||||||
@@ -72,23 +72,23 @@ METHOD(kernel_listener_t, acquire, bool,
|
|||||||
}
|
}
|
||||||
|
|
||||||
METHOD(kernel_listener_t, expire, bool,
|
METHOD(kernel_listener_t, expire, bool,
|
||||||
private_kernel_handler_t *this, u_int32_t reqid, u_int8_t protocol,
|
private_kernel_handler_t *this, u_int8_t protocol, u_int32_t spi,
|
||||||
u_int32_t spi, bool hard)
|
host_t *dst, bool hard)
|
||||||
{
|
{
|
||||||
protocol_id_t proto = proto_ip2ike(protocol);
|
protocol_id_t proto = proto_ip2ike(protocol);
|
||||||
|
|
||||||
DBG1(DBG_KNL, "creating %s job for %N CHILD_SA with SPI %.8x and reqid {%u}",
|
DBG1(DBG_KNL, "creating %s job for CHILD_SA %N/0x%08x/%H",
|
||||||
hard ? "delete" : "rekey", protocol_id_names, proto, ntohl(spi), reqid);
|
hard ? "delete" : "rekey", protocol_id_names, proto, ntohl(spi), dst);
|
||||||
|
|
||||||
if (hard)
|
if (hard)
|
||||||
{
|
{
|
||||||
lib->processor->queue_job(lib->processor,
|
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
|
else
|
||||||
{
|
{
|
||||||
lib->processor->queue_job(lib->processor,
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -222,10 +222,10 @@ static inline bool policy_entry_equals(policy_entry_t *a,
|
|||||||
/**
|
/**
|
||||||
* Expiration callback
|
* 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,
|
hydra->kernel_interface->expire(hydra->kernel_interface, protocol,
|
||||||
spi, hard);
|
spi, dst, hard);
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(kernel_ipsec_t, get_features, kernel_feature_t,
|
METHOD(kernel_ipsec_t, get_features, kernel_feature_t,
|
||||||
|
|||||||
@@ -2032,9 +2032,8 @@ static void expire_data_destroy(expire_data_t *data)
|
|||||||
static job_requeue_t expire_job(expire_data_t *data)
|
static job_requeue_t expire_job(expire_data_t *data)
|
||||||
{
|
{
|
||||||
private_kernel_wfp_ipsec_t *this = data->this;
|
private_kernel_wfp_ipsec_t *this = data->this;
|
||||||
u_int32_t reqid = 0;
|
|
||||||
u_int8_t protocol;
|
u_int8_t protocol;
|
||||||
entry_t *entry;
|
entry_t *entry = NULL;
|
||||||
sa_entry_t key = {
|
sa_entry_t key = {
|
||||||
.spi = data->spi,
|
.spi = data->spi,
|
||||||
.dst = data->dst,
|
.dst = data->dst,
|
||||||
@@ -2048,7 +2047,6 @@ static job_requeue_t expire_job(expire_data_t *data)
|
|||||||
if (entry)
|
if (entry)
|
||||||
{
|
{
|
||||||
protocol = entry->isa.protocol;
|
protocol = entry->isa.protocol;
|
||||||
reqid = entry->reqid;
|
|
||||||
if (entry->osa.dst)
|
if (entry->osa.dst)
|
||||||
{
|
{
|
||||||
key.dst = entry->osa.dst;
|
key.dst = entry->osa.dst;
|
||||||
@@ -2065,15 +2063,14 @@ static job_requeue_t expire_job(expire_data_t *data)
|
|||||||
if (entry)
|
if (entry)
|
||||||
{
|
{
|
||||||
protocol = entry->isa.protocol;
|
protocol = entry->isa.protocol;
|
||||||
reqid = entry->reqid;
|
|
||||||
}
|
}
|
||||||
this->mutex->unlock(this->mutex);
|
this->mutex->unlock(this->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reqid)
|
if (entry)
|
||||||
{
|
{
|
||||||
hydra->kernel_interface->expire(hydra->kernel_interface,
|
hydra->kernel_interface->expire(hydra->kernel_interface, protocol,
|
||||||
reqid, protocol, data->spi, data->hard);
|
data->spi, data->dst, data->hard);
|
||||||
}
|
}
|
||||||
|
|
||||||
return JOB_REQUEUE_NONE;
|
return JOB_REQUEUE_NONE;
|
||||||
|
|||||||
@@ -432,13 +432,13 @@ METHOD(stroke_control_t, rekey, void,
|
|||||||
while (children->enumerate(children, (void**)&child_sa))
|
while (children->enumerate(children, (void**)&child_sa))
|
||||||
{
|
{
|
||||||
if ((name && streq(name, child_sa->get_name(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,
|
lib->processor->queue_job(lib->processor,
|
||||||
(job_t*)rekey_child_sa_job_create(
|
(job_t*)rekey_child_sa_job_create(
|
||||||
child_sa->get_reqid(child_sa),
|
|
||||||
child_sa->get_protocol(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)
|
if (!all)
|
||||||
{
|
{
|
||||||
finished = TRUE;
|
finished = TRUE;
|
||||||
|
|||||||
@@ -30,11 +30,6 @@ struct private_delete_child_sa_job_t {
|
|||||||
*/
|
*/
|
||||||
delete_child_sa_job_t public;
|
delete_child_sa_job_t public;
|
||||||
|
|
||||||
/**
|
|
||||||
* reqid of the CHILD_SA
|
|
||||||
*/
|
|
||||||
u_int32_t reqid;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* protocol of the CHILD_SA (ESP/AH)
|
* protocol of the CHILD_SA (ESP/AH)
|
||||||
*/
|
*/
|
||||||
@@ -45,6 +40,11 @@ struct private_delete_child_sa_job_t {
|
|||||||
*/
|
*/
|
||||||
u_int32_t spi;
|
u_int32_t spi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SA destination address
|
||||||
|
*/
|
||||||
|
host_t *dst;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete for an expired CHILD_SA
|
* Delete for an expired CHILD_SA
|
||||||
*/
|
*/
|
||||||
@@ -54,6 +54,7 @@ struct private_delete_child_sa_job_t {
|
|||||||
METHOD(job_t, destroy, void,
|
METHOD(job_t, destroy, void,
|
||||||
private_delete_child_sa_job_t *this)
|
private_delete_child_sa_job_t *this)
|
||||||
{
|
{
|
||||||
|
this->dst->destroy(this->dst);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,12 +63,12 @@ METHOD(job_t, execute, job_requeue_t,
|
|||||||
{
|
{
|
||||||
ike_sa_t *ike_sa;
|
ike_sa_t *ike_sa;
|
||||||
|
|
||||||
ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
|
ike_sa = charon->child_sa_manager->checkout(charon->child_sa_manager,
|
||||||
this->reqid, TRUE);
|
this->protocol, this->spi, this->dst, NULL);
|
||||||
if (ike_sa == NULL)
|
if (ike_sa == NULL)
|
||||||
{
|
{
|
||||||
DBG1(DBG_JOB, "CHILD_SA with reqid %d not found for delete",
|
DBG1(DBG_JOB, "CHILD_SA %N/0x%08x/%H not found for delete",
|
||||||
this->reqid);
|
protocol_id_names, this->protocol, htonl(this->spi), this->dst);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -87,8 +88,8 @@ METHOD(job_t, get_priority, job_priority_t,
|
|||||||
/*
|
/*
|
||||||
* Described in header
|
* Described in header
|
||||||
*/
|
*/
|
||||||
delete_child_sa_job_t *delete_child_sa_job_create(u_int32_t reqid,
|
delete_child_sa_job_t *delete_child_sa_job_create(protocol_id_t protocol,
|
||||||
protocol_id_t protocol, u_int32_t spi, bool expired)
|
u_int32_t spi, host_t *dst, bool expired)
|
||||||
{
|
{
|
||||||
private_delete_child_sa_job_t *this;
|
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,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
.reqid = reqid,
|
|
||||||
.protocol = protocol,
|
.protocol = protocol,
|
||||||
.spi = spi,
|
.spi = spi,
|
||||||
|
.dst = dst->clone(dst),
|
||||||
.expired = expired,
|
.expired = expired,
|
||||||
);
|
);
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,16 +44,13 @@ struct delete_child_sa_job_t {
|
|||||||
/**
|
/**
|
||||||
* Creates a job of type DELETE_CHILD_SA.
|
* 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 protocol protocol of the CHILD_SA
|
||||||
* @param spi security parameter index 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
|
* @param expired TRUE if CHILD_SA already expired
|
||||||
* @return delete_child_sa_job_t object
|
* @return delete_child_sa_job_t object
|
||||||
*/
|
*/
|
||||||
delete_child_sa_job_t *delete_child_sa_job_create(u_int32_t reqid,
|
delete_child_sa_job_t *delete_child_sa_job_create(protocol_id_t protocol,
|
||||||
protocol_id_t protocol, u_int32_t spi, bool expired);
|
u_int32_t spi, host_t *dst, bool expired);
|
||||||
|
|
||||||
#endif /** DELETE_CHILD_SA_JOB_H_ @}*/
|
#endif /** DELETE_CHILD_SA_JOB_H_ @}*/
|
||||||
|
|||||||
@@ -24,16 +24,12 @@ typedef struct private_rekey_child_sa_job_t private_rekey_child_sa_job_t;
|
|||||||
* Private data of an rekey_child_sa_job_t object.
|
* Private data of an rekey_child_sa_job_t object.
|
||||||
*/
|
*/
|
||||||
struct private_rekey_child_sa_job_t {
|
struct private_rekey_child_sa_job_t {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Public rekey_child_sa_job_t interface.
|
* Public rekey_child_sa_job_t interface.
|
||||||
*/
|
*/
|
||||||
rekey_child_sa_job_t public;
|
rekey_child_sa_job_t public;
|
||||||
|
|
||||||
/**
|
|
||||||
* reqid of the child to rekey
|
|
||||||
*/
|
|
||||||
u_int32_t reqid;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* protocol of the CHILD_SA (ESP/AH)
|
* protocol of the CHILD_SA (ESP/AH)
|
||||||
*/
|
*/
|
||||||
@@ -43,11 +39,17 @@ struct private_rekey_child_sa_job_t {
|
|||||||
* inbound SPI of the CHILD_SA
|
* inbound SPI of the CHILD_SA
|
||||||
*/
|
*/
|
||||||
u_int32_t spi;
|
u_int32_t spi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SA destination address
|
||||||
|
*/
|
||||||
|
host_t *dst;
|
||||||
};
|
};
|
||||||
|
|
||||||
METHOD(job_t, destroy, void,
|
METHOD(job_t, destroy, void,
|
||||||
private_rekey_child_sa_job_t *this)
|
private_rekey_child_sa_job_t *this)
|
||||||
{
|
{
|
||||||
|
this->dst->destroy(this->dst);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,12 +58,12 @@ METHOD(job_t, execute, job_requeue_t,
|
|||||||
{
|
{
|
||||||
ike_sa_t *ike_sa;
|
ike_sa_t *ike_sa;
|
||||||
|
|
||||||
ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
|
ike_sa = charon->child_sa_manager->checkout(charon->child_sa_manager,
|
||||||
this->reqid, TRUE);
|
this->protocol, this->spi, this->dst, NULL);
|
||||||
if (ike_sa == NULL)
|
if (ike_sa == NULL)
|
||||||
{
|
{
|
||||||
DBG2(DBG_JOB, "CHILD_SA with reqid %d not found for rekeying",
|
DBG1(DBG_JOB, "CHILD_SA %N/0x%08x/%H not found for rekey",
|
||||||
this->reqid);
|
protocol_id_names, this->protocol, htonl(this->spi), this->dst);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -80,9 +82,8 @@ METHOD(job_t, get_priority, job_priority_t,
|
|||||||
/*
|
/*
|
||||||
* Described in header
|
* Described in header
|
||||||
*/
|
*/
|
||||||
rekey_child_sa_job_t *rekey_child_sa_job_create(u_int32_t reqid,
|
rekey_child_sa_job_t *rekey_child_sa_job_create(protocol_id_t protocol,
|
||||||
protocol_id_t protocol,
|
u_int32_t spi, host_t *dst)
|
||||||
u_int32_t spi)
|
|
||||||
{
|
{
|
||||||
private_rekey_child_sa_job_t *this;
|
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,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
.reqid = reqid,
|
|
||||||
.protocol = protocol,
|
.protocol = protocol,
|
||||||
.spi = spi,
|
.spi = spi,
|
||||||
|
.dst = dst->clone(dst),
|
||||||
);
|
);
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
|
|||||||
@@ -43,15 +43,11 @@ struct rekey_child_sa_job_t {
|
|||||||
/**
|
/**
|
||||||
* Creates a job of type REKEY_CHILD_SA.
|
* 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 protocol protocol of the CHILD_SA
|
||||||
* @param spi security parameter index 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
|
* @return rekey_child_sa_job_t object
|
||||||
*/
|
*/
|
||||||
rekey_child_sa_job_t *rekey_child_sa_job_create(u_int32_t reqid,
|
rekey_child_sa_job_t *rekey_child_sa_job_create(protocol_id_t protocol,
|
||||||
protocol_id_t protocol,
|
u_int32_t spi, host_t *dst);
|
||||||
u_int32_t spi);
|
|
||||||
#endif /** REKEY_CHILD_SA_JOB_H_ @}*/
|
#endif /** REKEY_CHILD_SA_JOB_H_ @}*/
|
||||||
|
|||||||
@@ -96,9 +96,9 @@ static void schedule_delayed_rekey(private_child_rekey_t *this)
|
|||||||
|
|
||||||
retry = RETRY_INTERVAL - (random() % RETRY_JITTER);
|
retry = RETRY_INTERVAL - (random() % RETRY_JITTER);
|
||||||
job = (job_t*)rekey_child_sa_job_create(
|
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_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);
|
DBG1(DBG_IKE, "CHILD_SA rekeying failed, trying again in %d seconds", retry);
|
||||||
this->child_sa->set_state(this->child_sa, CHILD_INSTALLED);
|
this->child_sa->set_state(this->child_sa, CHILD_INSTALLED);
|
||||||
lib->scheduler->schedule_job(lib->scheduler, job, retry);
|
lib->scheduler->schedule_job(lib->scheduler, job, retry);
|
||||||
|
|||||||
@@ -815,17 +815,18 @@ METHOD(kernel_interface_t, acquire, void,
|
|||||||
}
|
}
|
||||||
|
|
||||||
METHOD(kernel_interface_t, expire, void,
|
METHOD(kernel_interface_t, expire, void,
|
||||||
private_kernel_interface_t *this, u_int32_t reqid, u_int8_t protocol,
|
private_kernel_interface_t *this, u_int8_t protocol, u_int32_t spi,
|
||||||
u_int32_t spi, bool hard)
|
host_t *dst, bool hard)
|
||||||
{
|
{
|
||||||
kernel_listener_t *listener;
|
kernel_listener_t *listener;
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
|
|
||||||
this->mutex->lock(this->mutex);
|
this->mutex->lock(this->mutex);
|
||||||
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->expire &&
|
if (listener->expire &&
|
||||||
!listener->expire(listener, reqid, protocol, spi, hard))
|
!listener->expire(listener, protocol, spi, dst, hard))
|
||||||
{
|
{
|
||||||
this->listeners->remove_at(this->listeners, enumerator);
|
this->listeners->remove_at(this->listeners, enumerator);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -559,13 +559,13 @@ struct kernel_interface_t {
|
|||||||
/**
|
/**
|
||||||
* Raise an expire event.
|
* Raise an expire event.
|
||||||
*
|
*
|
||||||
* @param reqid reqid of the expired SA
|
|
||||||
* @param protocol protocol of the expired SA
|
* @param protocol protocol of the expired SA
|
||||||
* @param spi spi 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
|
* @param hard TRUE if it is a hard expire, FALSE otherwise
|
||||||
*/
|
*/
|
||||||
void (*expire)(kernel_interface_t *this, u_int32_t reqid,
|
void (*expire)(kernel_interface_t *this, u_int8_t protocol, u_int32_t spi,
|
||||||
u_int8_t protocol, u_int32_t spi, bool hard);
|
host_t *dst, bool hard);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Raise a mapping event.
|
* Raise a mapping event.
|
||||||
|
|||||||
@@ -49,14 +49,14 @@ struct kernel_listener_t {
|
|||||||
/**
|
/**
|
||||||
* Hook called if an exire event for an IPsec SA is received.
|
* 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 protocol protocol of the expired SA
|
||||||
* @param spi spi 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
|
* @param hard TRUE if it is a hard expire, FALSE otherwise
|
||||||
* @return TRUE to remain registered, FALSE to unregister
|
* @return TRUE to remain registered, FALSE to unregister
|
||||||
*/
|
*/
|
||||||
bool (*expire)(kernel_listener_t *this, u_int32_t reqid,
|
bool (*expire)(kernel_listener_t *this, u_int8_t protocol, u_int32_t spi,
|
||||||
u_int8_t protocol, u_int32_t spi, bool hard);
|
host_t *dst, bool hard);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook called if the NAT mappings of an IPsec SA changed.
|
* Hook called if the NAT mappings of an IPsec SA changed.
|
||||||
|
|||||||
@@ -870,25 +870,26 @@ static void process_expire(private_kernel_netlink_ipsec_t *this,
|
|||||||
struct nlmsghdr *hdr)
|
struct nlmsghdr *hdr)
|
||||||
{
|
{
|
||||||
struct xfrm_user_expire *expire;
|
struct xfrm_user_expire *expire;
|
||||||
u_int32_t spi, reqid;
|
u_int32_t spi;
|
||||||
u_int8_t protocol;
|
u_int8_t protocol;
|
||||||
|
host_t *dst;
|
||||||
|
|
||||||
expire = NLMSG_DATA(hdr);
|
expire = NLMSG_DATA(hdr);
|
||||||
protocol = expire->state.id.proto;
|
protocol = expire->state.id.proto;
|
||||||
spi = expire->state.id.spi;
|
spi = expire->state.id.spi;
|
||||||
reqid = expire->state.reqid;
|
|
||||||
|
|
||||||
DBG2(DBG_KNL, "received a XFRM_MSG_EXPIRE");
|
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 "
|
dst = xfrm2host(expire->state.family, &expire->state.id.daddr, 0);
|
||||||
"reqid {%u} which is not a CHILD_SA", ntohl(spi), reqid);
|
if (dst)
|
||||||
return;
|
{
|
||||||
|
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1296,7 +1296,8 @@ static void process_expire(private_kernel_pfkey_ipsec_t *this,
|
|||||||
{
|
{
|
||||||
pfkey_msg_t response;
|
pfkey_msg_t response;
|
||||||
u_int8_t protocol;
|
u_int8_t protocol;
|
||||||
u_int32_t spi, reqid;
|
u_int32_t spi;
|
||||||
|
host_t *dst;
|
||||||
bool hard;
|
bool hard;
|
||||||
|
|
||||||
DBG2(DBG_KNL, "received an SADB_EXPIRE");
|
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);
|
protocol = satype2proto(msg->sadb_msg_satype);
|
||||||
spi = response.sa->sadb_sa_spi;
|
spi = response.sa->sadb_sa_spi;
|
||||||
reqid = response.x_sa2->sadb_x_sa2_reqid;
|
|
||||||
hard = response.lft_hard != NULL;
|
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 "
|
dst = host_create_from_sockaddr((sockaddr_t*)(response.dst + 1));
|
||||||
"reqid {%u} which is not a CHILD_SA", ntohl(spi), reqid);
|
if (dst)
|
||||||
return;
|
{
|
||||||
|
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
|
#ifdef SADB_X_MIGRATE
|
||||||
|
|||||||
@@ -35,14 +35,12 @@ struct ipsec_event_listener_t {
|
|||||||
/**
|
/**
|
||||||
* Called when the lifetime of an IPsec SA expired
|
* Called when the lifetime of an IPsec SA expired
|
||||||
*
|
*
|
||||||
* @param reqid reqid of the expired SA
|
|
||||||
* @param protocol protocol of the expired SA
|
* @param protocol protocol of the expired SA
|
||||||
* @param spi spi 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
|
* @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,
|
void (*expire)(u_int8_t protocol, u_int32_t spi, host_t *dst, bool hard);
|
||||||
bool hard);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /** IPSEC_EVENT_LISTENER_H_ @}*/
|
#endif /** IPSEC_EVENT_LISTENER_H_ @}*/
|
||||||
|
|||||||
@@ -65,23 +65,26 @@ typedef struct {
|
|||||||
} type;
|
} 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
|
* SPI of the SA, if any
|
||||||
*/
|
*/
|
||||||
u_int32_t spi;
|
u_int32_t spi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SA destination address
|
||||||
|
*/
|
||||||
|
host_t *dst;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Additional data for specific event types
|
* Additional data for specific event types
|
||||||
*/
|
*/
|
||||||
union {
|
union {
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
/** Protocol of the SA */
|
|
||||||
u_int8_t protocol;
|
|
||||||
/** TRUE in case of a hard expire */
|
/** TRUE in case of a hard expire */
|
||||||
bool hard;
|
bool hard;
|
||||||
} expire;
|
} expire;
|
||||||
@@ -90,6 +93,15 @@ typedef struct {
|
|||||||
|
|
||||||
} ipsec_event_t;
|
} 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
|
* Dequeue events and relay them to listeners
|
||||||
*/
|
*/
|
||||||
@@ -110,31 +122,31 @@ static job_requeue_t handle_events(private_ipsec_event_relay_t *this)
|
|||||||
case IPSEC_EVENT_EXPIRE:
|
case IPSEC_EVENT_EXPIRE:
|
||||||
if (current->expire)
|
if (current->expire)
|
||||||
{
|
{
|
||||||
current->expire(event->reqid, event->data.expire.protocol,
|
current->expire(event->protocol, event->spi, event->dst,
|
||||||
event->spi, event->data.expire.hard);
|
event->data.expire.hard);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
this->lock->unlock(this->lock);
|
this->lock->unlock(this->lock);
|
||||||
free(event);
|
ipsec_event_destroy(event);
|
||||||
return JOB_REQUEUE_DIRECT;
|
return JOB_REQUEUE_DIRECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(ipsec_event_relay_t, expire, void,
|
METHOD(ipsec_event_relay_t, expire, void,
|
||||||
private_ipsec_event_relay_t *this, u_int32_t reqid, u_int8_t protocol,
|
private_ipsec_event_relay_t *this, u_int8_t protocol, u_int32_t spi,
|
||||||
u_int32_t spi, bool hard)
|
host_t *dst, bool hard)
|
||||||
{
|
{
|
||||||
ipsec_event_t *event;
|
ipsec_event_t *event;
|
||||||
|
|
||||||
INIT(event,
|
INIT(event,
|
||||||
.type = IPSEC_EVENT_EXPIRE,
|
.type = IPSEC_EVENT_EXPIRE,
|
||||||
.reqid = reqid,
|
.protocol = protocol,
|
||||||
.spi = spi,
|
.spi = spi,
|
||||||
|
.dst = dst->clone(dst),
|
||||||
.data = {
|
.data = {
|
||||||
.expire = {
|
.expire = {
|
||||||
.protocol = protocol,
|
|
||||||
.hard = hard,
|
.hard = hard,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -38,13 +38,13 @@ struct ipsec_event_relay_t {
|
|||||||
/**
|
/**
|
||||||
* Raise an expire event.
|
* Raise an expire event.
|
||||||
*
|
*
|
||||||
* @param reqid reqid of the expired IPsec SA
|
|
||||||
* @param protocol protocol (e.g ESP) of the expired SA
|
* @param protocol protocol (e.g ESP) of the expired SA
|
||||||
* @param spi SPI 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
|
* @param hard TRUE for a hard expire, FALSE otherwise
|
||||||
*/
|
*/
|
||||||
void (*expire)(ipsec_event_relay_t *this, u_int32_t reqid,
|
void (*expire)(ipsec_event_relay_t *this, u_int8_t protocol, u_int32_t spi,
|
||||||
u_int8_t protocol, u_int32_t spi, bool hard);
|
host_t *dst, bool hard);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a listener to events raised by this manager
|
* Register a listener to events raised by this manager
|
||||||
|
|||||||
@@ -194,8 +194,8 @@ METHOD(ipsec_sa_t, expire, void,
|
|||||||
if (!this->hard_expired)
|
if (!this->hard_expired)
|
||||||
{
|
{
|
||||||
this->hard_expired = TRUE;
|
this->hard_expired = TRUE;
|
||||||
ipsec->events->expire(ipsec->events, this->reqid, this->protocol,
|
ipsec->events->expire(ipsec->events, this->protocol, this->spi,
|
||||||
this->spi, TRUE);
|
this->dst, TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -203,8 +203,8 @@ METHOD(ipsec_sa_t, expire, void,
|
|||||||
if (!this->hard_expired && !this->soft_expired)
|
if (!this->hard_expired && !this->soft_expired)
|
||||||
{
|
{
|
||||||
this->soft_expired = TRUE;
|
this->soft_expired = TRUE;
|
||||||
ipsec->events->expire(ipsec->events, this->reqid, this->protocol,
|
ipsec->events->expire(ipsec->events, this->protocol, this->spi,
|
||||||
this->spi, FALSE);
|
this->dst, FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user