kernel-interface: Add a separate "update" flag to add_sa()

The current "inbound" flag is used for two purposes: To define the actual
direction of the SA, but also to determine the operation used for SA
installation. If an SPI has been allocated, an update operation is required
instead of an add.

While the inbound flag normally defines the kind of operation required, this
is not necessarily true in all cases. On the HA passive node, we install inbound
SAs without prior SPI allocation.
This commit is contained in:
Martin Willi
2015-03-09 18:18:20 +01:00
parent 68e5ada005
commit 942797a5b5
10 changed files with 19 additions and 17 deletions
+1 -1
View File
@@ -86,7 +86,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window,
bool initiator, bool encap, bool esn, bool inbound,
bool initiator, bool encap, bool esn, bool inbound, bool update,
linked_list_t* src_ts, linked_list_t* dst_ts)
{
esa_info_t esa;
@@ -254,7 +254,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window,
bool initiator, bool encap, bool esn, bool inbound,
bool initiator, bool encap, bool esn, bool inbound, bool update,
linked_list_t *src_ts, linked_list_t *dst_ts)
{
return ipsec->sas->add_sa(ipsec->sas, src, dst, spi, protocol, reqid, mark,
@@ -2103,7 +2103,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window,
bool initiator, bool encap, bool esn, bool inbound,
bool initiator, bool encap, bool esn, bool inbound, bool update,
linked_list_t *src_ts, linked_list_t *dst_ts)
{
host_t *local, *remote;
@@ -55,7 +55,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window,
bool initiator, bool encap, bool esn, bool inbound,
bool initiator, bool encap, bool esn, bool inbound, bool update,
linked_list_t *src_ts, linked_list_t *dst_ts)
{
return SUCCESS;
+1 -1
View File
@@ -750,7 +750,7 @@ METHOD(child_sa_t, install, status_t,
inbound ? this->mark_in : this->mark_out, tfc,
lifetime, enc_alg, encr, int_alg, integ, this->mode,
this->ipcomp, cpi, this->config->get_replay_window(this->config),
initiator, this->encap, esn, update, src_ts, dst_ts);
initiator, this->encap, esn, inbound, update, src_ts, dst_ts);
free(lifetime);
+2 -2
View File
@@ -421,7 +421,7 @@ METHOD(kernel_interface_t, add_sa, status_t,
u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window,
bool initiator, bool encap, bool esn, bool inbound,
bool initiator, bool encap, bool esn, bool inbound, bool update,
linked_list_t *src_ts, linked_list_t *dst_ts)
{
if (!this->ipsec)
@@ -431,7 +431,7 @@ METHOD(kernel_interface_t, add_sa, status_t,
return this->ipsec->add_sa(this->ipsec, src, dst, spi, protocol, reqid,
mark, tfc, lifetime, enc_alg, enc_key, int_alg, int_key, mode,
ipcomp, cpi, replay_window, initiator, encap, esn, inbound,
src_ts, dst_ts);
update, src_ts, dst_ts);
}
METHOD(kernel_interface_t, update_sa, status_t,
+3 -2
View File
@@ -180,6 +180,7 @@ struct kernel_interface_t {
* @param encap enable UDP encapsulation for NAT traversal
* @param esn TRUE to use Extended Sequence Numbers
* @param inbound TRUE if this is an inbound SA
* @param update TRUE if an SPI has already been allocated for SA
* @param src_ts list of source traffic selectors
* @param dst_ts list of destination traffic selectors
* @return SUCCESS if operation completed
@@ -191,8 +192,8 @@ struct kernel_interface_t {
u_int16_t enc_alg, chunk_t enc_key,
u_int16_t int_alg, chunk_t int_key,
ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi,
u_int32_t replay_window,
bool initiator, bool encap, bool esn, bool inbound,
u_int32_t replay_window, bool initiator, bool encap,
bool esn, bool inbound, bool update,
linked_list_t *src_ts, linked_list_t *dst_ts);
/**
+3 -2
View File
@@ -101,6 +101,7 @@ struct kernel_ipsec_t {
* @param encap enable UDP encapsulation for NAT traversal
* @param esn TRUE to use Extended Sequence Numbers
* @param inbound TRUE if this is an inbound SA
* @param update TRUE if an SPI has already been allocated for SA
* @param src_ts list of source traffic selectors
* @param dst_ts list of destination traffic selectors
* @return SUCCESS if operation completed
@@ -112,8 +113,8 @@ struct kernel_ipsec_t {
u_int16_t enc_alg, chunk_t enc_key,
u_int16_t int_alg, chunk_t int_key,
ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi,
u_int32_t replay_window,
bool initiator, bool encap, bool esn, bool inbound,
u_int32_t replay_window, bool initiator, bool encap,
bool esn, bool inbound, bool update,
linked_list_t *src_ts, linked_list_t *dst_ts);
/**
@@ -1197,7 +1197,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window,
bool initiator, bool encap, bool esn, bool inbound,
bool initiator, bool encap, bool esn, bool inbound, bool update,
linked_list_t* src_ts, linked_list_t* dst_ts)
{
netlink_buf_t request;
@@ -1217,7 +1217,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
add_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, reqid, mark,
tfc, &lft, ENCR_UNDEFINED, chunk_empty, AUTH_UNDEFINED,
chunk_empty, mode, ipcomp, 0, 0, initiator, FALSE, FALSE,
inbound, src_ts, dst_ts);
inbound, update, src_ts, dst_ts);
ipcomp = IPCOMP_NONE;
/* use transport mode ESP SA, IPComp uses tunnel mode */
mode = MODE_TRANSPORT;
@@ -1230,7 +1230,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
hdr = &request.hdr;
hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
hdr->nlmsg_type = inbound ? XFRM_MSG_UPDSA : XFRM_MSG_NEWSA;
hdr->nlmsg_type = update ? XFRM_MSG_UPDSA : XFRM_MSG_NEWSA;
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_info));
sa = NLMSG_DATA(hdr);
@@ -1615,7 +1615,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window,
bool initiator, bool encap, bool esn, bool inbound,
bool initiator, bool encap, bool esn, bool inbound, bool update,
linked_list_t *src_ts, linked_list_t *dst_ts)
{
unsigned char request[PFKEY_BUFFER_SIZE];
@@ -1634,13 +1634,13 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
add_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, reqid, mark,
tfc, &lft, ENCR_UNDEFINED, chunk_empty, AUTH_UNDEFINED,
chunk_empty, mode, ipcomp, 0, 0, FALSE, FALSE, FALSE, inbound,
NULL, NULL);
update, NULL, NULL);
ipcomp = IPCOMP_NONE;
/* use transport mode ESP SA, IPComp uses tunnel mode */
mode = MODE_TRANSPORT;
}
if (inbound)
if (update)
{
/* As we didn't know the reqid during SPI allocation, we used reqid
* zero. Unfortunately we can't SADB_UPDATE to the new reqid, hence we