libipsec: Support usage statistics and query_sa() on IPsec SAs
This commit is contained in:
@@ -91,6 +91,7 @@ static void deliver_inbound(private_ipsec_processor_t *this,
|
||||
static job_requeue_t process_inbound(private_ipsec_processor_t *this)
|
||||
{
|
||||
esp_packet_t *packet;
|
||||
ip_packet_t *ip_packet;
|
||||
ipsec_sa_t *sa;
|
||||
u_int8_t next_header;
|
||||
u_int32_t spi, reqid;
|
||||
@@ -126,6 +127,8 @@ static job_requeue_t process_inbound(private_ipsec_processor_t *this)
|
||||
packet->destroy(packet);
|
||||
return JOB_REQUEUE_DIRECT;
|
||||
}
|
||||
ip_packet = packet->get_payload(packet);
|
||||
sa->update_usestats(sa, ip_packet->get_encoding(ip_packet).len);
|
||||
reqid = sa->get_reqid(sa);
|
||||
ipsec->sas->checkin(ipsec->sas, sa);
|
||||
|
||||
@@ -136,13 +139,11 @@ static job_requeue_t process_inbound(private_ipsec_processor_t *this)
|
||||
case IPPROTO_IPV6:
|
||||
{
|
||||
ipsec_policy_t *policy;
|
||||
ip_packet_t *ip_packet;
|
||||
|
||||
ip_packet = packet->get_payload(packet);
|
||||
policy = ipsec->policies->find_by_packet(ipsec->policies,
|
||||
ip_packet, TRUE, reqid);
|
||||
if (policy)
|
||||
{ /* TODO-IPSEC: update policy/sa stats? */
|
||||
{
|
||||
deliver_inbound(this, packet);
|
||||
policy->destroy(policy);
|
||||
break;
|
||||
@@ -225,7 +226,7 @@ static job_requeue_t process_outbound(private_ipsec_processor_t *this)
|
||||
policy->destroy(policy);
|
||||
return JOB_REQUEUE_DIRECT;
|
||||
}
|
||||
/* TODO-IPSEC: update policy/sa counters? */
|
||||
sa->update_usestats(sa, packet->get_encoding(packet).len);
|
||||
ipsec->sas->checkin(ipsec->sas, sa);
|
||||
policy->destroy(policy);
|
||||
send_outbound(this, esp_packet);
|
||||
|
||||
@@ -81,6 +81,18 @@ struct private_ipsec_sa_t {
|
||||
* ESP context
|
||||
*/
|
||||
esp_context_t *esp_context;
|
||||
|
||||
/**
|
||||
* Usage statistics
|
||||
*/
|
||||
struct {
|
||||
/** last time of use */
|
||||
time_t time;
|
||||
/** number of packets processed */
|
||||
u_int64_t packets;
|
||||
/** number of bytes processed */
|
||||
u_int64_t bytes;
|
||||
} use;
|
||||
};
|
||||
|
||||
METHOD(ipsec_sa_t, get_source, host_t*,
|
||||
@@ -145,6 +157,32 @@ METHOD(ipsec_sa_t, get_esp_context, esp_context_t*,
|
||||
return this->esp_context;
|
||||
}
|
||||
|
||||
METHOD(ipsec_sa_t, get_usestats, void,
|
||||
private_ipsec_sa_t *this, u_int64_t *bytes, u_int64_t *packets,
|
||||
time_t *time)
|
||||
{
|
||||
if (bytes)
|
||||
{
|
||||
*bytes = this->use.bytes;
|
||||
}
|
||||
if (packets)
|
||||
{
|
||||
*packets = this->use.packets;
|
||||
}
|
||||
if (time)
|
||||
{
|
||||
*time = this->use.time;
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(ipsec_sa_t, update_usestats, void,
|
||||
private_ipsec_sa_t *this, u_int32_t bytes)
|
||||
{
|
||||
this->use.time = time_monotonic(NULL);
|
||||
this->use.packets++;
|
||||
this->use.bytes += bytes;
|
||||
}
|
||||
|
||||
METHOD(ipsec_sa_t, match_by_spi_dst, bool,
|
||||
private_ipsec_sa_t *this, u_int32_t spi, host_t *dst)
|
||||
{
|
||||
@@ -227,6 +265,8 @@ ipsec_sa_t *ipsec_sa_create(u_int32_t spi, host_t *src, host_t *dst,
|
||||
.match_by_spi_src_dst = _match_by_spi_src_dst,
|
||||
.match_by_reqid = _match_by_reqid,
|
||||
.get_esp_context = _get_esp_context,
|
||||
.get_usestats = _get_usestats,
|
||||
.update_usestats = _update_usestats,
|
||||
},
|
||||
.spi = spi,
|
||||
.src = src->clone(src),
|
||||
|
||||
@@ -109,6 +109,23 @@ struct ipsec_sa_t {
|
||||
*/
|
||||
esp_context_t *(*get_esp_context)(ipsec_sa_t *this);
|
||||
|
||||
/**
|
||||
* Get usage statistics for this SA.
|
||||
*
|
||||
* @param bytes receives number of processed bytes, or NULL
|
||||
* @param packets receives number of processed packets, or NULL
|
||||
* @param time receives last use time of this SA, or NULL
|
||||
*/
|
||||
void (*get_usestats)(ipsec_sa_t *this, u_int64_t *bytes, u_int64_t *packets,
|
||||
time_t *time);
|
||||
|
||||
/**
|
||||
* Record en/decryption of a packet to update usage statistics.
|
||||
*
|
||||
* @param bytes length of packet processed
|
||||
*/
|
||||
void (*update_usestats)(ipsec_sa_t *this, u_int32_t bytes);
|
||||
|
||||
/**
|
||||
* Check if this SA matches all given parameters
|
||||
*
|
||||
|
||||
@@ -530,6 +530,28 @@ METHOD(ipsec_sa_mgr_t, update_sa, status_t,
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(ipsec_sa_mgr_t, query_sa, status_t,
|
||||
private_ipsec_sa_mgr_t *this, host_t *src, host_t *dst,
|
||||
u_int32_t spi, u_int8_t protocol, mark_t mark,
|
||||
u_int64_t *bytes, u_int64_t *packets, time_t *time)
|
||||
{
|
||||
ipsec_sa_entry_t *entry = NULL;
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
if (this->sas->find_first(this->sas, (void*)match_entry_by_spi_src_dst,
|
||||
(void**)&entry, &spi, src, dst) == SUCCESS &&
|
||||
wait_for_entry(this, entry))
|
||||
{
|
||||
entry->sa->get_usestats(entry->sa, bytes, packets, time);
|
||||
/* checkin the entry */
|
||||
entry->locked = FALSE;
|
||||
entry->condvar->signal(entry->condvar);
|
||||
}
|
||||
this->mutex->unlock(this->mutex);
|
||||
|
||||
return entry ? SUCCESS : NOT_FOUND;
|
||||
}
|
||||
|
||||
METHOD(ipsec_sa_mgr_t, del_sa, status_t,
|
||||
private_ipsec_sa_mgr_t *this, host_t *src, host_t *dst, u_int32_t spi,
|
||||
u_int8_t protocol, u_int16_t cpi, mark_t mark)
|
||||
@@ -653,6 +675,7 @@ ipsec_sa_mgr_t *ipsec_sa_mgr_create()
|
||||
.get_spi = _get_spi,
|
||||
.add_sa = _add_sa,
|
||||
.update_sa = _update_sa,
|
||||
.query_sa = _query_sa,
|
||||
.del_sa = _del_sa,
|
||||
.checkout_by_spi = _checkout_by_spi,
|
||||
.checkout_by_reqid = _checkout_by_reqid,
|
||||
|
||||
@@ -108,6 +108,23 @@ struct ipsec_sa_mgr_t {
|
||||
host_t *new_src, host_t *new_dst,
|
||||
bool encap, bool new_encap, mark_t mark);
|
||||
|
||||
/**
|
||||
* Query the number of bytes processed by an SA from the SAD.
|
||||
*
|
||||
* @param src source address for this SA
|
||||
* @param dst destination address for this SA
|
||||
* @param spi SPI allocated by us or remote peer
|
||||
* @param protocol protocol for this SA (ESP/AH)
|
||||
* @param mark optional mark for this SA
|
||||
* @param[out] bytes the number of bytes processed by SA
|
||||
* @param[out] packets number of packets processed by SA
|
||||
* @param[out] time last (monotonic) time of SA use
|
||||
* @return SUCCESS if operation completed
|
||||
*/
|
||||
status_t (*query_sa)(ipsec_sa_mgr_t *this, host_t *src, host_t *dst,
|
||||
u_int32_t spi, u_int8_t protocol, mark_t mark,
|
||||
u_int64_t *bytes, u_int64_t *packets, time_t *time);
|
||||
|
||||
/**
|
||||
* Delete a previously added SA
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user