kernel-interface: query SAD for last use time if SPD query didn't yield one
This commit is contained in:
parent
bdaf9f97e6
commit
5c12700f9a
|
@ -216,7 +216,7 @@ sad_failure:
|
||||||
METHOD(kernel_ipsec_t, query_sa, status_t,
|
METHOD(kernel_ipsec_t, query_sa, status_t,
|
||||||
private_tkm_kernel_ipsec_t *this, host_t *src, host_t *dst,
|
private_tkm_kernel_ipsec_t *this, host_t *src, host_t *dst,
|
||||||
u_int32_t spi, u_int8_t protocol, mark_t mark, u_int64_t *bytes,
|
u_int32_t spi, u_int8_t protocol, mark_t mark, u_int64_t *bytes,
|
||||||
u_int64_t *packets)
|
u_int64_t *packets, u_int32_t *time)
|
||||||
{
|
{
|
||||||
return NOT_SUPPORTED;
|
return NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
|
||||||
METHOD(kernel_ipsec_t, query_sa, status_t,
|
METHOD(kernel_ipsec_t, query_sa, status_t,
|
||||||
private_kernel_android_ipsec_t *this, host_t *src, host_t *dst,
|
private_kernel_android_ipsec_t *this, host_t *src, host_t *dst,
|
||||||
u_int32_t spi, u_int8_t protocol, mark_t mark,
|
u_int32_t spi, u_int8_t protocol, mark_t mark,
|
||||||
u_int64_t *bytes, u_int64_t *packets)
|
u_int64_t *bytes, u_int64_t *packets, u_int32_t *time)
|
||||||
{
|
{
|
||||||
return NOT_SUPPORTED;
|
return NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
|
||||||
METHOD(kernel_ipsec_t, query_sa, status_t,
|
METHOD(kernel_ipsec_t, query_sa, status_t,
|
||||||
private_load_tester_ipsec_t *this, host_t *src, host_t *dst,
|
private_load_tester_ipsec_t *this, host_t *src, host_t *dst,
|
||||||
u_int32_t spi, u_int8_t protocol, mark_t mark,
|
u_int32_t spi, u_int8_t protocol, mark_t mark,
|
||||||
u_int64_t *bytes, u_int64_t *packets)
|
u_int64_t *bytes, u_int64_t *packets, u_int32_t *time)
|
||||||
{
|
{
|
||||||
return NOT_SUPPORTED;
|
return NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
|
@ -424,6 +424,7 @@ static status_t update_usebytes(private_child_sa_t *this, bool inbound)
|
||||||
{
|
{
|
||||||
status_t status = FAILED;
|
status_t status = FAILED;
|
||||||
u_int64_t bytes, packets;
|
u_int64_t bytes, packets;
|
||||||
|
u_int32_t time;
|
||||||
|
|
||||||
if (inbound)
|
if (inbound)
|
||||||
{
|
{
|
||||||
|
@ -432,13 +433,17 @@ static status_t update_usebytes(private_child_sa_t *this, bool inbound)
|
||||||
status = hydra->kernel_interface->query_sa(hydra->kernel_interface,
|
status = hydra->kernel_interface->query_sa(hydra->kernel_interface,
|
||||||
this->other_addr, this->my_addr, this->my_spi,
|
this->other_addr, this->my_addr, this->my_spi,
|
||||||
proto_ike2ip(this->protocol), this->mark_in,
|
proto_ike2ip(this->protocol), this->mark_in,
|
||||||
&bytes, &packets);
|
&bytes, &packets, &time);
|
||||||
if (status == SUCCESS)
|
if (status == SUCCESS)
|
||||||
{
|
{
|
||||||
if (bytes > this->my_usebytes)
|
if (bytes > this->my_usebytes)
|
||||||
{
|
{
|
||||||
this->my_usebytes = bytes;
|
this->my_usebytes = bytes;
|
||||||
this->my_usepackets = packets;
|
this->my_usepackets = packets;
|
||||||
|
if (time)
|
||||||
|
{
|
||||||
|
this->my_usetime = time;
|
||||||
|
}
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
return FAILED;
|
return FAILED;
|
||||||
|
@ -452,13 +457,17 @@ static status_t update_usebytes(private_child_sa_t *this, bool inbound)
|
||||||
status = hydra->kernel_interface->query_sa(hydra->kernel_interface,
|
status = hydra->kernel_interface->query_sa(hydra->kernel_interface,
|
||||||
this->my_addr, this->other_addr, this->other_spi,
|
this->my_addr, this->other_addr, this->other_spi,
|
||||||
proto_ike2ip(this->protocol), this->mark_out,
|
proto_ike2ip(this->protocol), this->mark_out,
|
||||||
&bytes, &packets);
|
&bytes, &packets, &time);
|
||||||
if (status == SUCCESS)
|
if (status == SUCCESS)
|
||||||
{
|
{
|
||||||
if (bytes > this->other_usebytes)
|
if (bytes > this->other_usebytes)
|
||||||
{
|
{
|
||||||
this->other_usebytes = bytes;
|
this->other_usebytes = bytes;
|
||||||
this->other_usepackets = packets;
|
this->other_usepackets = packets;
|
||||||
|
if (time)
|
||||||
|
{
|
||||||
|
this->other_usetime = time;
|
||||||
|
}
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
return FAILED;
|
return FAILED;
|
||||||
|
@ -471,7 +480,7 @@ static status_t update_usebytes(private_child_sa_t *this, bool inbound)
|
||||||
/**
|
/**
|
||||||
* updates the cached usetime
|
* updates the cached usetime
|
||||||
*/
|
*/
|
||||||
static void update_usetime(private_child_sa_t *this, bool inbound)
|
static bool update_usetime(private_child_sa_t *this, bool inbound)
|
||||||
{
|
{
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
traffic_selector_t *my_ts, *other_ts;
|
traffic_selector_t *my_ts, *other_ts;
|
||||||
|
@ -511,7 +520,7 @@ static void update_usetime(private_child_sa_t *this, bool inbound)
|
||||||
|
|
||||||
if (last_use == 0)
|
if (last_use == 0)
|
||||||
{
|
{
|
||||||
return;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (inbound)
|
if (inbound)
|
||||||
{
|
{
|
||||||
|
@ -521,6 +530,7 @@ static void update_usetime(private_child_sa_t *this, bool inbound)
|
||||||
{
|
{
|
||||||
this->other_usetime = last_use;
|
this->other_usetime = last_use;
|
||||||
}
|
}
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(child_sa_t, get_usestats, void,
|
METHOD(child_sa_t, get_usestats, void,
|
||||||
|
@ -534,7 +544,11 @@ METHOD(child_sa_t, get_usestats, void,
|
||||||
*/
|
*/
|
||||||
if (time)
|
if (time)
|
||||||
{
|
{
|
||||||
update_usetime(this, inbound);
|
if (!update_usetime(this, inbound) && !bytes && !packets)
|
||||||
|
{
|
||||||
|
/* if policy query did not yield a usetime, query SAs instead */
|
||||||
|
update_usebytes(this, inbound);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (time)
|
if (time)
|
||||||
|
|
|
@ -208,14 +208,14 @@ METHOD(kernel_interface_t, update_sa, status_t,
|
||||||
METHOD(kernel_interface_t, query_sa, status_t,
|
METHOD(kernel_interface_t, query_sa, status_t,
|
||||||
private_kernel_interface_t *this, host_t *src, host_t *dst,
|
private_kernel_interface_t *this, host_t *src, host_t *dst,
|
||||||
u_int32_t spi, u_int8_t protocol, mark_t mark,
|
u_int32_t spi, u_int8_t protocol, mark_t mark,
|
||||||
u_int64_t *bytes, u_int64_t *packets)
|
u_int64_t *bytes, u_int64_t *packets, u_int32_t *time)
|
||||||
{
|
{
|
||||||
if (!this->ipsec)
|
if (!this->ipsec)
|
||||||
{
|
{
|
||||||
return NOT_SUPPORTED;
|
return NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
return this->ipsec->query_sa(this->ipsec, src, dst, spi, protocol, mark,
|
return this->ipsec->query_sa(this->ipsec, src, dst, spi, protocol, mark,
|
||||||
bytes, packets);
|
bytes, packets, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(kernel_interface_t, del_sa, status_t,
|
METHOD(kernel_interface_t, del_sa, status_t,
|
||||||
|
|
|
@ -197,11 +197,12 @@ struct kernel_interface_t {
|
||||||
* @param mark optional mark for this SA
|
* @param mark optional mark for this SA
|
||||||
* @param[out] bytes the number of bytes processed by SA
|
* @param[out] bytes the number of bytes processed by SA
|
||||||
* @param[out] packets number of packets processed by SA
|
* @param[out] packets number of packets processed by SA
|
||||||
|
* @param[out] time last time of SA use
|
||||||
* @return SUCCESS if operation completed
|
* @return SUCCESS if operation completed
|
||||||
*/
|
*/
|
||||||
status_t (*query_sa) (kernel_interface_t *this, host_t *src, host_t *dst,
|
status_t (*query_sa) (kernel_interface_t *this, host_t *src, host_t *dst,
|
||||||
u_int32_t spi, u_int8_t protocol, mark_t mark,
|
u_int32_t spi, u_int8_t protocol, mark_t mark,
|
||||||
u_int64_t *bytes, u_int64_t *packets);
|
u_int64_t *bytes, u_int64_t *packets, u_int32_t *time);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a previously installed SA from the SAD.
|
* Delete a previously installed SA from the SAD.
|
||||||
|
|
|
@ -155,11 +155,12 @@ struct kernel_ipsec_t {
|
||||||
* @param mark optional mark for this SA
|
* @param mark optional mark for this SA
|
||||||
* @param[out] bytes the number of bytes processed by SA
|
* @param[out] bytes the number of bytes processed by SA
|
||||||
* @param[out] packets number of packets processed by SA
|
* @param[out] packets number of packets processed by SA
|
||||||
|
* @param[out] time last time of SA use
|
||||||
* @return SUCCESS if operation completed
|
* @return SUCCESS if operation completed
|
||||||
*/
|
*/
|
||||||
status_t (*query_sa) (kernel_ipsec_t *this, host_t *src, host_t *dst,
|
status_t (*query_sa) (kernel_ipsec_t *this, host_t *src, host_t *dst,
|
||||||
u_int32_t spi, u_int8_t protocol, mark_t mark,
|
u_int32_t spi, u_int8_t protocol, mark_t mark,
|
||||||
u_int64_t *bytes, u_int64_t *packets);
|
u_int64_t *bytes, u_int64_t *packets, u_int32_t *time);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a previusly installed SA from the SAD.
|
* Delete a previusly installed SA from the SAD.
|
||||||
|
|
|
@ -1911,7 +1911,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
|
||||||
METHOD(kernel_ipsec_t, query_sa, status_t,
|
METHOD(kernel_ipsec_t, query_sa, status_t,
|
||||||
private_kernel_klips_ipsec_t *this, host_t *src, host_t *dst,
|
private_kernel_klips_ipsec_t *this, host_t *src, host_t *dst,
|
||||||
u_int32_t spi, u_int8_t protocol, mark_t mark,
|
u_int32_t spi, u_int8_t protocol, mark_t mark,
|
||||||
u_int64_t *bytes, u_int64_t *packets)
|
u_int64_t *bytes, u_int64_t *packets, u_int32_t *time)
|
||||||
{
|
{
|
||||||
return NOT_SUPPORTED; /* TODO */
|
return NOT_SUPPORTED; /* TODO */
|
||||||
}
|
}
|
||||||
|
|
|
@ -1595,7 +1595,7 @@ static void get_replay_state(private_kernel_netlink_ipsec_t *this,
|
||||||
METHOD(kernel_ipsec_t, query_sa, status_t,
|
METHOD(kernel_ipsec_t, query_sa, status_t,
|
||||||
private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst,
|
private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst,
|
||||||
u_int32_t spi, u_int8_t protocol, mark_t mark,
|
u_int32_t spi, u_int8_t protocol, mark_t mark,
|
||||||
u_int64_t *bytes, u_int64_t *packets)
|
u_int64_t *bytes, u_int64_t *packets, u_int32_t *time)
|
||||||
{
|
{
|
||||||
netlink_buf_t request;
|
netlink_buf_t request;
|
||||||
struct nlmsghdr *out = NULL, *hdr;
|
struct nlmsghdr *out = NULL, *hdr;
|
||||||
|
@ -1680,6 +1680,12 @@ METHOD(kernel_ipsec_t, query_sa, status_t,
|
||||||
{
|
{
|
||||||
*packets = sa->curlft.packets;
|
*packets = sa->curlft.packets;
|
||||||
}
|
}
|
||||||
|
if (time)
|
||||||
|
{ /* curlft contains an "use" time, but that contains a timestamp
|
||||||
|
* of the first use, not the last. Last use time must be queried
|
||||||
|
* on the policy on Linux */
|
||||||
|
*time = 0;
|
||||||
|
}
|
||||||
status = SUCCESS;
|
status = SUCCESS;
|
||||||
}
|
}
|
||||||
memwipe(out, len);
|
memwipe(out, len);
|
||||||
|
|
|
@ -1804,7 +1804,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
|
||||||
METHOD(kernel_ipsec_t, query_sa, status_t,
|
METHOD(kernel_ipsec_t, query_sa, status_t,
|
||||||
private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst,
|
private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst,
|
||||||
u_int32_t spi, u_int8_t protocol, mark_t mark,
|
u_int32_t spi, u_int8_t protocol, mark_t mark,
|
||||||
u_int64_t *bytes, u_int64_t *packets)
|
u_int64_t *bytes, u_int64_t *packets, u_int32_t *time)
|
||||||
{
|
{
|
||||||
unsigned char request[PFKEY_BUFFER_SIZE];
|
unsigned char request[PFKEY_BUFFER_SIZE];
|
||||||
struct sadb_msg *msg, *out;
|
struct sadb_msg *msg, *out;
|
||||||
|
@ -1862,6 +1862,18 @@ METHOD(kernel_ipsec_t, query_sa, status_t,
|
||||||
/* not supported by PF_KEY */
|
/* not supported by PF_KEY */
|
||||||
*packets = 0;
|
*packets = 0;
|
||||||
}
|
}
|
||||||
|
if (time)
|
||||||
|
{
|
||||||
|
#ifdef __APPLE__
|
||||||
|
/* OS X uses the "last" time of use in usetime */
|
||||||
|
*time = response.lft_current->sadb_lifetime_usetime;
|
||||||
|
#else /* !__APPLE__ */
|
||||||
|
/* on Linux, sadb_lifetime_usetime is set to the "first" time of use,
|
||||||
|
* which is actually correct according to PF_KEY. We have to query
|
||||||
|
* policies for the last usetime. */
|
||||||
|
*time = 0;
|
||||||
|
#endif /* !__APPLE__ */
|
||||||
|
}
|
||||||
|
|
||||||
free(out);
|
free(out);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
|
@ -2435,7 +2447,7 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
|
||||||
}
|
}
|
||||||
else if (response.lft_current == NULL)
|
else if (response.lft_current == NULL)
|
||||||
{
|
{
|
||||||
DBG1(DBG_KNL, "unable to query policy %R === %R %N: kernel reports no "
|
DBG2(DBG_KNL, "unable to query policy %R === %R %N: kernel reports no "
|
||||||
"use time", src_ts, dst_ts, policy_dir_names, direction);
|
"use time", src_ts, dst_ts, policy_dir_names, direction);
|
||||||
free(out);
|
free(out);
|
||||||
return FAILED;
|
return FAILED;
|
||||||
|
|
Loading…
Reference in New Issue