mirror of
https://github.com/strongswan/strongswan.git
synced 2025-10-04 00:00:14 -04:00
kernel-netlink: Don't add replay state twice when updating SAs
The kernel includes the XFRMA_REPLAY_ESN_VAL attribute when dumping SAs since it was added with 2.6.39. So we basically added this attribute twice to the message sent to the kernel, potentially exceeding the message buffer if the window size is large. The XFRMA_REPLAY_VAL attribute is only dumped since 3.19, so that might still be relevant (Google seems to maintain a 3.18 kernel) and since we have to query the current lifetime stats anyway, we can just avoid adding this attribute twice. Closes strongswan/strongswan#1967
This commit is contained in:
parent
b345eb3051
commit
3cb8434367
@ -2121,14 +2121,13 @@ failed:
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ESN replay state (i.e. sequence numbers) of an SA.
|
||||
* Get the usage stats (packets/bytes) and classic replay state (i.e. sequence
|
||||
* numbers for small windows/non-ESN) of an SA.
|
||||
*
|
||||
* Allocates into one the replay state structure we get from the kernel.
|
||||
* Allocates and copies the attributes we get from the kernel.
|
||||
*/
|
||||
static void get_replay_state(private_kernel_netlink_ipsec_t *this,
|
||||
kernel_ipsec_sa_id_t *sa,
|
||||
struct xfrm_replay_state_esn **replay_esn,
|
||||
uint32_t *replay_esn_len,
|
||||
struct xfrm_replay_state **replay,
|
||||
struct xfrm_lifetime_cur **lifetime)
|
||||
{
|
||||
@ -2214,14 +2213,6 @@ static void get_replay_state(private_kernel_netlink_ipsec_t *this,
|
||||
*replay = malloc(RTA_PAYLOAD(rta));
|
||||
memcpy(*replay, RTA_DATA(rta), RTA_PAYLOAD(rta));
|
||||
}
|
||||
if (rta->rta_type == XFRMA_REPLAY_ESN_VAL &&
|
||||
RTA_PAYLOAD(rta) >= sizeof(**replay_esn))
|
||||
{
|
||||
free(*replay_esn);
|
||||
*replay_esn = malloc(RTA_PAYLOAD(rta));
|
||||
*replay_esn_len = RTA_PAYLOAD(rta);
|
||||
memcpy(*replay_esn, RTA_DATA(rta), RTA_PAYLOAD(rta));
|
||||
}
|
||||
rta = RTA_NEXT(rta, rtasize);
|
||||
}
|
||||
}
|
||||
@ -2433,7 +2424,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
|
||||
struct xfrm_replay_state *replay = NULL;
|
||||
struct xfrm_replay_state_esn *replay_esn = NULL;
|
||||
struct xfrm_lifetime_cur *lifetime = NULL;
|
||||
uint32_t replay_esn_len = 0;
|
||||
bool replay_state_seen = FALSE;
|
||||
kernel_ipsec_del_sa_t del = { 0 };
|
||||
status_t status = FAILED;
|
||||
traffic_selector_t *ts;
|
||||
@ -2518,8 +2509,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
|
||||
goto failed;
|
||||
}
|
||||
|
||||
get_replay_state(this, id, &replay_esn, &replay_esn_len, &replay,
|
||||
&lifetime);
|
||||
get_replay_state(this, id, &replay, &lifetime);
|
||||
|
||||
/* delete the old SA (without affecting the IPComp SA) */
|
||||
if (del_sa(this, id, &del) != SUCCESS)
|
||||
@ -2600,6 +2590,11 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
|
||||
free(ifname);
|
||||
}
|
||||
}
|
||||
if (rta->rta_type == XFRMA_REPLAY_ESN_VAL ||
|
||||
rta->rta_type == XFRMA_REPLAY_VAL)
|
||||
{
|
||||
replay_state_seen = TRUE;
|
||||
}
|
||||
netlink_add_attribute(hdr, rta->rta_type,
|
||||
chunk_create(RTA_DATA(rta), RTA_PAYLOAD(rta)),
|
||||
sizeof(request));
|
||||
@ -2621,19 +2616,9 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
|
||||
memset(&encap->encap_oa, 0, sizeof (xfrm_address_t));
|
||||
}
|
||||
|
||||
if (replay_esn)
|
||||
if (!replay_state_seen)
|
||||
{
|
||||
struct xfrm_replay_state_esn *state;
|
||||
|
||||
state = netlink_reserve(hdr, sizeof(request), XFRMA_REPLAY_ESN_VAL,
|
||||
replay_esn_len);
|
||||
if (!state)
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
memcpy(state, replay_esn, replay_esn_len);
|
||||
}
|
||||
else if (replay)
|
||||
if (replay)
|
||||
{
|
||||
struct xfrm_replay_state *state;
|
||||
|
||||
@ -2650,6 +2635,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
|
||||
DBG1(DBG_KNL, "unable to copy replay state from old SAD entry with "
|
||||
"SPI %.8x%s", ntohl(id->spi), markstr);
|
||||
}
|
||||
}
|
||||
if (lifetime)
|
||||
{
|
||||
struct xfrm_lifetime_cur *state;
|
||||
|
Loading…
x
Reference in New Issue
Block a user