conftest: Make outgoing sequence number set by reset_seq configurable
This is useful for certain test cases. Passing the sequence number to the callback requires a new struct that contains both the number and the xfrm_usersa_id. The new configuration parameter is called oseq in accordance with the kernel name, see the comment in the reset_cb callback function for details.
This commit is contained in:
committed by
Martin Willi
parent
ff318ad3e1
commit
4e51cf895e
@@ -239,6 +239,7 @@ Currently, the following hooks are defined with the following options:
|
|||||||
rebuild_auth: rebuild AUTH payload, i.e. if ID payload changed
|
rebuild_auth: rebuild AUTH payload, i.e. if ID payload changed
|
||||||
reset_seq: Reset sequence numbers of an ESP SA
|
reset_seq: Reset sequence numbers of an ESP SA
|
||||||
delay: Seconds to delay reset after SA established
|
delay: Seconds to delay reset after SA established
|
||||||
|
oseq: Sequence number to set, default is 0
|
||||||
set_critical: Set critical bit on existing payloads:
|
set_critical: Set critical bit on existing payloads:
|
||||||
request: yes to set in request, no in response
|
request: yes to set in request, no in response
|
||||||
id: IKEv2 message identifier of message to mangle payloads
|
id: IKEv2 message identifier of message to mangle payloads
|
||||||
|
|||||||
@@ -12,6 +12,27 @@
|
|||||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
* for more details.
|
* for more details.
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2012 achelos GmbH
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "hook.h"
|
#include "hook.h"
|
||||||
|
|
||||||
@@ -40,21 +61,46 @@ struct private_reset_seq_t {
|
|||||||
* Delay for reset
|
* Delay for reset
|
||||||
*/
|
*/
|
||||||
int delay;
|
int delay;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sequence number to set for outgoing packages
|
||||||
|
*/
|
||||||
|
int oseq;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct reset_cb_data_t reset_cb_data_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data needed for the callback job
|
||||||
|
*/
|
||||||
|
struct reset_cb_data_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The SA to modify
|
||||||
|
*/
|
||||||
|
struct xfrm_usersa_id usersa;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sequence number to set for outgoing packages
|
||||||
|
*/
|
||||||
|
int oseq;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback job
|
* Callback job
|
||||||
*/
|
*/
|
||||||
static job_requeue_t reset_cb(struct xfrm_usersa_id *data)
|
static job_requeue_t reset_cb(struct reset_cb_data_t *data)
|
||||||
{
|
{
|
||||||
netlink_buf_t request;
|
netlink_buf_t request;
|
||||||
struct nlmsghdr *hdr;
|
struct nlmsghdr *hdr;
|
||||||
struct xfrm_aevent_id *id;
|
struct xfrm_aevent_id *id;
|
||||||
struct rtattr *rthdr;
|
struct rtattr *rthdr;
|
||||||
|
struct xfrm_replay_state *rpstate;
|
||||||
struct sockaddr_nl addr;
|
struct sockaddr_nl addr;
|
||||||
int s, len;
|
int s, len;
|
||||||
|
|
||||||
DBG1(DBG_CFG, "resetting sequence number of SPI 0x%x", htonl(data->spi));
|
DBG1(DBG_CFG, "setting sequence number of SPI 0x%x to %d",
|
||||||
|
htonl(data->usersa.spi), data->oseq);
|
||||||
|
|
||||||
memset(&request, 0, sizeof(request));
|
memset(&request, 0, sizeof(request));
|
||||||
|
|
||||||
@@ -66,13 +112,22 @@ static job_requeue_t reset_cb(struct xfrm_usersa_id *data)
|
|||||||
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_aevent_id));
|
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_aevent_id));
|
||||||
|
|
||||||
id = (struct xfrm_aevent_id*)NLMSG_DATA(hdr);
|
id = (struct xfrm_aevent_id*)NLMSG_DATA(hdr);
|
||||||
id->sa_id = *data;
|
id->sa_id = data->usersa;
|
||||||
|
|
||||||
rthdr = XFRM_RTA(hdr, struct xfrm_aevent_id);
|
rthdr = XFRM_RTA(hdr, struct xfrm_aevent_id);
|
||||||
rthdr->rta_type = XFRMA_REPLAY_VAL;
|
rthdr->rta_type = XFRMA_REPLAY_VAL;
|
||||||
rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_replay_state));
|
rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_replay_state));
|
||||||
hdr->nlmsg_len += rthdr->rta_len;
|
hdr->nlmsg_len += rthdr->rta_len;
|
||||||
|
|
||||||
|
/* xfrm_replay_state is the structure the kernel uses for
|
||||||
|
* replay detection, and the oseq element contains the
|
||||||
|
* sequence number for outgoing packets. Currently, this
|
||||||
|
* function sets the other elements seq (records the number of
|
||||||
|
* incoming packets) and bitmask to zero, but they could be
|
||||||
|
* adjusted in the same way as oseq if required. */
|
||||||
|
rpstate = (struct xfrm_replay_state*)RTA_DATA(rthdr);
|
||||||
|
rpstate->oseq = data->oseq;
|
||||||
|
|
||||||
s = socket(AF_NETLINK, SOCK_RAW, NETLINK_XFRM);
|
s = socket(AF_NETLINK, SOCK_RAW, NETLINK_XFRM);
|
||||||
if (s == -1)
|
if (s == -1)
|
||||||
{
|
{
|
||||||
@@ -97,17 +152,21 @@ static job_requeue_t reset_cb(struct xfrm_usersa_id *data)
|
|||||||
static void schedule_reset_job(private_reset_seq_t *this, host_t *dst,
|
static void schedule_reset_job(private_reset_seq_t *this, host_t *dst,
|
||||||
u_int32_t spi)
|
u_int32_t spi)
|
||||||
{
|
{
|
||||||
struct xfrm_usersa_id *data;
|
struct reset_cb_data_t *data;
|
||||||
chunk_t chunk;
|
chunk_t chunk;
|
||||||
|
|
||||||
INIT(data,
|
INIT(data,
|
||||||
.spi = spi,
|
.usersa = {
|
||||||
.family = dst->get_family(dst),
|
.spi = spi,
|
||||||
.proto = IPPROTO_ESP,
|
.family = dst->get_family(dst),
|
||||||
|
.proto = IPPROTO_ESP,
|
||||||
|
},
|
||||||
|
.oseq = this->oseq,
|
||||||
);
|
);
|
||||||
|
|
||||||
chunk = dst->get_address(dst);
|
chunk = dst->get_address(dst);
|
||||||
memcpy(&data->daddr, chunk.ptr, min(chunk.len, sizeof(xfrm_address_t)));
|
memcpy(&data->usersa.daddr, chunk.ptr,
|
||||||
|
min(chunk.len, sizeof(xfrm_address_t)));
|
||||||
|
|
||||||
lib->scheduler->schedule_job(lib->scheduler,
|
lib->scheduler->schedule_job(lib->scheduler,
|
||||||
(job_t*)callback_job_create(
|
(job_t*)callback_job_create(
|
||||||
@@ -149,6 +208,8 @@ hook_t *reset_seq_hook_create(char *name)
|
|||||||
},
|
},
|
||||||
.delay = conftest->test->get_int(conftest->test,
|
.delay = conftest->test->get_int(conftest->test,
|
||||||
"hooks.%s.delay", 10, name),
|
"hooks.%s.delay", 10, name),
|
||||||
|
.oseq = conftest->test->get_int(conftest->test,
|
||||||
|
"hooks.%s.oseq", 0, name),
|
||||||
);
|
);
|
||||||
|
|
||||||
return &this->hook;
|
return &this->hook;
|
||||||
|
|||||||
Reference in New Issue
Block a user