display transmitted bytes per SA

This commit is contained in:
Andreas Steffen
2009-07-30 21:33:19 +02:00
parent eab05274f4
commit 2ad51539f6
10 changed files with 203 additions and 19 deletions
+14
View File
@@ -103,6 +103,19 @@ static status_t update_sa(private_kernel_interface_t *this, u_int32_t spi,
new_src, new_dst, encap, new_encap);
}
/**
* Implementation of kernel_interface_t.query_sa
*/
static status_t query_sa(private_kernel_interface_t *this, host_t *src, host_t *dst,
u_int32_t spi, protocol_id_t protocol, u_int64_t *bytes)
{
if (!this->ipsec)
{
return NOT_SUPPORTED;
}
return this->ipsec->query_sa(this->ipsec, src, dst, spi, protocol, bytes);
}
/**
* Implementation of kernel_interface_t.del_sa
*/
@@ -387,6 +400,7 @@ kernel_interface_t *kernel_interface_create()
this->public.get_cpi = (status_t(*)(kernel_interface_t*,host_t*,host_t*,u_int32_t,u_int16_t*))get_cpi;
this->public.add_sa = (status_t(*)(kernel_interface_t *,host_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t,u_int64_t,u_int64_t,u_int16_t,chunk_t,u_int16_t,chunk_t,ipsec_mode_t,u_int16_t,u_int16_t,bool,bool))add_sa;
this->public.update_sa = (status_t(*)(kernel_interface_t*,u_int32_t,protocol_id_t,u_int16_t,host_t*,host_t*,host_t*,host_t*,bool,bool))update_sa;
this->public.query_sa = (status_t(*)(kernel_interface_t*,host_t*,host_t*,u_int32_t,protocol_id_t,u_int64_t*))query_sa;
this->public.del_sa = (status_t(*)(kernel_interface_t*,host_t*,host_t*,u_int32_t,protocol_id_t,u_int16_t))del_sa;
this->public.add_policy = (status_t(*)(kernel_interface_t*,host_t*,host_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t,protocol_id_t,u_int32_t,ipsec_mode_t,u_int16_t,u_int16_t,bool))add_policy;
this->public.query_policy = (status_t(*)(kernel_interface_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t*))query_policy;
+13
View File
@@ -140,6 +140,19 @@ struct kernel_interface_t {
host_t *new_src, host_t *new_dst,
bool encap, bool new_encap);
/**
* 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[out] bytes the number of bytes processed by SA
* @return SUCCESS if operation completed
*/
status_t (*query_sa) (kernel_interface_t *this, host_t *src, host_t *dst,
u_int32_t spi, protocol_id_t protocol, u_int64_t *bytes);
/**
* Delete a previously installed SA from the SAD.
*
+13
View File
@@ -170,6 +170,19 @@ struct kernel_ipsec_t {
host_t *new_src, host_t *new_dst,
bool encap, bool new_encap);
/**
* 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[out] bytes the number of bytes processed by SA
* @return SUCCESS if operation completed
*/
status_t (*query_sa) (kernel_ipsec_t *this, host_t *src, host_t *dst,
u_int32_t spi, protocol_id_t protocol, u_int64_t *bytes);
/**
* Delete a previusly installed SA from the SAD.
*
@@ -1933,6 +1933,16 @@ static status_t update_sa(private_kernel_klips_ipsec_t *this,
return SUCCESS;
}
/**
* Implementation of kernel_interface_t.query_sa.
*/
static status_t query_sa(private_kernel_klips_ipsec_t *this, host_t *src,
host_t *dst, u_int32_t spi, protocol_id_t protocol,
u_int64_t *bytes)
{
return NOT_SUPPORTED; /* TODO */
}
/**
* Implementation of kernel_interface_t.del_sa.
*/
@@ -2609,6 +2619,7 @@ kernel_klips_ipsec_t *kernel_klips_ipsec_create()
this->public.interface.get_cpi = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,u_int16_t*))get_cpi;
this->public.interface.add_sa = (status_t(*)(kernel_ipsec_t *,host_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t,u_int64_t,u_int64_t,u_int16_t,chunk_t,u_int16_t,chunk_t,ipsec_mode_t,u_int16_t,u_int16_t,bool,bool))add_sa;
this->public.interface.update_sa = (status_t(*)(kernel_ipsec_t*,u_int32_t,protocol_id_t,u_int16_t,host_t*,host_t*,host_t*,host_t*,bool,bool))update_sa;
this->public.interface.query_sa = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,protocol_id_t,u_int64_t*))query_sa;
this->public.interface.del_sa = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,protocol_id_t,u_int16_t))del_sa;
this->public.interface.add_policy = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t,protocol_id_t,u_int32_t,ipsec_mode_t,u_int16_t,u_int16_t,bool))add_policy;
this->public.interface.query_policy = (status_t(*)(kernel_ipsec_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t*))query_policy;
@@ -1232,6 +1232,74 @@ static status_t get_replay_state(private_kernel_netlink_ipsec_t *this,
return FAILED;
}
/**
* Implementation of kernel_interface_t.query_sa.
*/
static status_t query_sa(private_kernel_netlink_ipsec_t *this, host_t *src,
host_t *dst, u_int32_t spi, protocol_id_t protocol,
u_int64_t *bytes)
{
netlink_buf_t request;
struct nlmsghdr *out = NULL, *hdr;
struct xfrm_usersa_id *sa_id;
struct xfrm_usersa_info *sa = NULL;
size_t len;
memset(&request, 0, sizeof(request));
DBG2(DBG_KNL, "querying SAD entry with SPI %.8x", ntohl(spi));
hdr = (struct nlmsghdr*)request;
hdr->nlmsg_flags = NLM_F_REQUEST;
hdr->nlmsg_type = XFRM_MSG_GETSA;
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_id));
sa_id = (struct xfrm_usersa_id*)NLMSG_DATA(hdr);
host2xfrm(dst, &sa_id->daddr);
sa_id->spi = spi;
sa_id->proto = proto_ike2kernel(protocol);
sa_id->family = dst->get_family(dst);
if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS)
{
hdr = out;
while (NLMSG_OK(hdr, len))
{
switch (hdr->nlmsg_type)
{
case XFRM_MSG_NEWSA:
{
sa = (struct xfrm_usersa_info*)NLMSG_DATA(hdr);
break;
}
case NLMSG_ERROR:
{
struct nlmsgerr *err = NLMSG_DATA(hdr);
DBG1(DBG_KNL, "querying SAD entry with SPI %.8x failed: %s (%d)",
ntohl(spi), strerror(-err->error), -err->error);
break;
}
default:
hdr = NLMSG_NEXT(hdr, len);
continue;
case NLMSG_DONE:
break;
}
break;
}
}
if (sa == NULL)
{
DBG2(DBG_KNL, "unable to query SAD entry with SPI %.8x", ntohl(spi));
free(out);
return FAILED;
}
*bytes = sa->curlft.bytes;
free(out);
return SUCCESS;
}
/**
* Implementation of kernel_interface_t.del_sa.
*/
@@ -1891,6 +1959,7 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create()
this->public.interface.get_cpi = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,u_int16_t*))get_cpi;
this->public.interface.add_sa = (status_t(*)(kernel_ipsec_t *,host_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t,u_int64_t,u_int64_t,u_int16_t,chunk_t,u_int16_t,chunk_t,ipsec_mode_t,u_int16_t,u_int16_t,bool,bool))add_sa;
this->public.interface.update_sa = (status_t(*)(kernel_ipsec_t*,u_int32_t,protocol_id_t,u_int16_t,host_t*,host_t*,host_t*,host_t*,bool,bool))update_sa;
this->public.interface.query_sa = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,protocol_id_t,u_int64_t*))query_sa;
this->public.interface.del_sa = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,protocol_id_t,u_int16_t))del_sa;
this->public.interface.add_policy = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t,protocol_id_t,u_int32_t,ipsec_mode_t,u_int16_t,u_int16_t,bool))add_policy;
this->public.interface.query_policy = (status_t(*)(kernel_ipsec_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t*))query_policy;
@@ -1488,6 +1488,16 @@ static status_t update_sa(private_kernel_pfkey_ipsec_t *this,
return SUCCESS;
}
/**
* Implementation of kernel_interface_t.query_sa.
*/
static status_t query_sa(private_kernel_pfkey_ipsec_t *this, host_t *src,
host_t *dst, u_int32_t spi, protocol_id_t protocol,
u_int64_t *bytes)
{
return NOT_SUPPORTED; /* TODO */
}
/**
* Implementation of kernel_interface_t.del_sa.
*/
@@ -2053,6 +2063,7 @@ kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create()
this->public.interface.get_cpi = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,u_int16_t*))get_cpi;
this->public.interface.add_sa = (status_t(*)(kernel_ipsec_t *,host_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t,u_int64_t,u_int64_t,u_int16_t,chunk_t,u_int16_t,chunk_t,ipsec_mode_t,u_int16_t,u_int16_t,bool,bool))add_sa;
this->public.interface.update_sa = (status_t(*)(kernel_ipsec_t*,u_int32_t,protocol_id_t,u_int16_t,host_t*,host_t*,host_t*,host_t*,bool,bool))update_sa;
this->public.interface.query_sa = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,protocol_id_t,u_int64_t*))query_sa;
this->public.interface.del_sa = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,protocol_id_t,u_int16_t))del_sa;
this->public.interface.add_policy = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t,protocol_id_t,u_int32_t,ipsec_mode_t,u_int16_t,u_int16_t,bool))add_policy;
this->public.interface.query_policy = (status_t(*)(kernel_ipsec_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t*))query_policy;
@@ -83,6 +83,16 @@ static status_t update_sa(private_load_tester_ipsec_t *this,
return SUCCESS;
}
/**
* Implementation of kernel_interface_t.query_sa.
*/
static status_t query_sa(private_load_tester_ipsec_t *this, host_t *src,
host_t *dst, u_int32_t spi, protocol_id_t protocol,
u_int64_t *bytes)
{
return NOT_SUPPORTED;
}
/**
* Implementation of kernel_interface_t.del_sa.
*/
@@ -151,6 +161,7 @@ load_tester_ipsec_t *load_tester_ipsec_create()
this->public.interface.get_cpi = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,u_int16_t*))get_cpi;
this->public.interface.add_sa = (status_t(*)(kernel_ipsec_t *,host_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t,u_int64_t,u_int64_t,u_int16_t,chunk_t,u_int16_t,chunk_t,ipsec_mode_t,u_int16_t,u_int16_t,bool,bool))add_sa;
this->public.interface.update_sa = (status_t(*)(kernel_ipsec_t*,u_int32_t,protocol_id_t,u_int16_t,host_t*,host_t*,host_t*,host_t*,bool,bool))update_sa;
this->public.interface.query_sa = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,protocol_id_t,u_int64_t*))query_sa;
this->public.interface.del_sa = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,protocol_id_t,u_int16_t))del_sa;
this->public.interface.add_policy = (status_t(*)(kernel_ipsec_t *this,host_t *, host_t *,traffic_selector_t *,traffic_selector_t *,policy_dir_t, u_int32_t,protocol_id_t, u_int32_t,ipsec_mode_t, u_int16_t, u_int16_t,bool))add_policy;
this->public.interface.query_policy = (status_t(*)(kernel_ipsec_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t*))query_policy;
+23 -19
View File
@@ -148,6 +148,7 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
{
u_int32_t rekey, now = time(NULL);
u_int32_t use_in, use_out;
u_int64_t bytes_in, bytes_out;
proposal_t *proposal;
child_cfg_t *config = child_sa->get_config(child_sa);
@@ -205,6 +206,28 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
}
}
}
bytes_in = child_sa->get_usebytes(child_sa, TRUE);
fprintf(out, ", %lu bytes_i", bytes_in);
if (bytes_in)
{
use_in = child_sa->get_usetime(child_sa, TRUE);
if (use_in)
{
fprintf(out, " (%ds ago)", now - use_in);
}
}
bytes_out = child_sa->get_usebytes(child_sa, FALSE);
fprintf(out, ", %lu bytes_o", bytes_out);
if (bytes_out)
{
use_out = child_sa->get_usetime(child_sa, FALSE);
if (use_out)
{
fprintf(out, " (%ds ago)", now - use_out);
}
}
fprintf(out, ", rekeying ");
rekey = child_sa->get_lifetime(child_sa, FALSE);
@@ -224,25 +247,6 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
fprintf(out, "disabled");
}
fprintf(out, ", last use: ");
use_in = child_sa->get_usetime(child_sa, TRUE);
if (use_in)
{
fprintf(out, "%ds_i ", now - use_in);
}
else
{
fprintf(out, "no_i ");
}
use_out = child_sa->get_usetime(child_sa, FALSE);
if (use_out)
{
fprintf(out, "%ds_o ", now - use_out);
}
else
{
fprintf(out, "no_o ");
}
}
}
+30
View File
@@ -397,6 +397,35 @@ static u_int32_t get_usetime(private_child_sa_t *this, bool inbound)
return last_use;
}
/**
* Implementation of child_sa_t.get_usebytes
*/
static u_int64_t get_usebytes(private_child_sa_t *this, bool inbound)
{
status_t status = NOT_SUPPORTED;
u_int64_t bytes;
if (inbound)
{
if (this->my_spi)
{
status = charon->kernel_interface->query_sa(charon->kernel_interface,
this->other_addr, this->my_addr,
this->my_spi, this->protocol, &bytes);
}
}
else
{
if (this->other_spi)
{
status = charon->kernel_interface->query_sa(charon->kernel_interface,
this->my_addr, this->other_addr,
this->other_spi, this->protocol, &bytes);
}
}
return (status == SUCCESS) ? bytes : 0;
}
/**
* Implementation of child_sa_t.get_lifetime
*/
@@ -776,6 +805,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
this->public.set_proposal = (void(*)(child_sa_t*, proposal_t *proposal))set_proposal;
this->public.get_lifetime = (u_int32_t(*)(child_sa_t*, bool))get_lifetime;
this->public.get_usetime = (u_int32_t(*)(child_sa_t*, bool))get_usetime;
this->public.get_usebytes = (u_int64_t(*)(child_sa_t*, bool))get_usebytes;
this->public.has_encap = (bool(*)(child_sa_t*))has_encap;
this->public.get_ipcomp = (ipcomp_transform_t(*)(child_sa_t*))get_ipcomp;
this->public.set_ipcomp = (void(*)(child_sa_t*,ipcomp_transform_t))set_ipcomp;
+8
View File
@@ -244,6 +244,14 @@ struct child_sa_t {
*/
u_int32_t (*get_usetime)(child_sa_t *this, bool inbound);
/**
* Get number of bytes processed by CHILD_SA.
*
* @param inbound TRUE for inbound traffic, FALSE for outbound
* @return number of processed bytes
*/
u_int64_t (*get_usebytes)(child_sa_t *this, bool inbound);
/**
* Get the traffic selectors list added for one side.
*