}
/**
- * 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)
{
*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);
}
}
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;
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)
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));
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)
+ if (replay)
{
- goto failed;
- }
- memcpy(state, replay_esn, replay_esn_len);
- }
- else if (replay)
- {
- struct xfrm_replay_state *state;
+ struct xfrm_replay_state *state;
- state = netlink_reserve(hdr, sizeof(request), XFRMA_REPLAY_VAL,
- sizeof(*state));
- if (!state)
+ state = netlink_reserve(hdr, sizeof(request), XFRMA_REPLAY_VAL,
+ sizeof(*state));
+ if (!state)
+ {
+ goto failed;
+ }
+ memcpy(state, replay, sizeof(*state));
+ }
+ else
{
- goto failed;
+ DBG1(DBG_KNL, "unable to copy replay state from old SAD entry with "
+ "SPI %.8x%s", ntohl(id->spi), markstr);
}
- memcpy(state, replay, sizeof(*state));
- }
- else
- {
- DBG1(DBG_KNL, "unable to copy replay state from old SAD entry with "
- "SPI %.8x%s", ntohl(id->spi), markstr);
}
if (lifetime)
{