diff options
author | Tobias Brunner <tobias@strongswan.org> | 2017-07-11 13:42:06 +0200 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2017-08-07 10:44:05 +0200 |
commit | a146b4c9efa46c537d04b5089a54f10dc106e14a (patch) | |
tree | 6ee3518c318ffdf0cfd8c5f601924cb8e5b1aa33 | |
parent | 2c116ef589b76b78216f5c61dfc1afefd3ae8f87 (diff) | |
download | strongswan-a146b4c9efa46c537d04b5089a54f10dc106e14a.tar.bz2 strongswan-a146b4c9efa46c537d04b5089a54f10dc106e14a.tar.xz |
child-sa: Install outbound SA immediately if kernel supports SPIs on policies
-rw-r--r-- | src/libcharon/sa/child_sa.c | 54 | ||||
-rw-r--r-- | src/libcharon/sa/child_sa.h | 13 | ||||
-rw-r--r-- | src/libcharon/sa/ikev2/tasks/child_create.c | 6 |
3 files changed, 47 insertions, 26 deletions
diff --git a/src/libcharon/sa/child_sa.c b/src/libcharon/sa/child_sa.c index 77d71ab15..6c6804c64 100644 --- a/src/libcharon/sa/child_sa.c +++ b/src/libcharon/sa/child_sa.c @@ -1271,21 +1271,35 @@ METHOD(child_sa_t, install_policies, status_t, return status; } -METHOD(child_sa_t, register_outbound, void, +METHOD(child_sa_t, register_outbound, status_t, private_child_sa_t *this, chunk_t encr, chunk_t integ, uint32_t spi, uint16_t cpi, bool tfcv3) { - DBG2(DBG_CHD, "registering outbound %N SA", protocol_id_names, - this->protocol); - DBG2(DBG_CHD, " SPI 0x%.8x, src %H dst %H", ntohl(spi), this->my_addr, - this->other_addr); - - this->other_spi = spi; - this->other_cpi = cpi; - this->encr_r = chunk_clone(encr); - this->integ_r = chunk_clone(integ); - this->tfcv3 = tfcv3; + status_t status; + + /* if the kernel supports installing SPIs with policies we install the + * SA immediately as it will only be used once we update the policies */ + if (charon->kernel->get_features(charon->kernel) & KERNEL_POLICY_SPI) + { + status = install_internal(this, encr, integ, spi, cpi, FALSE, FALSE, + tfcv3); + } + else + { + DBG2(DBG_CHD, "registering outbound %N SA", protocol_id_names, + this->protocol); + DBG2(DBG_CHD, " SPI 0x%.8x, src %H dst %H", ntohl(spi), this->my_addr, + this->other_addr); + + this->other_spi = spi; + this->other_cpi = cpi; + this->encr_r = chunk_clone(encr); + this->integ_r = chunk_clone(integ); + this->tfcv3 = tfcv3; + status = SUCCESS; + } this->outbound_state |= CHILD_OUTBOUND_REGISTERED; + return status; } METHOD(child_sa_t, install_outbound, status_t, @@ -1295,18 +1309,21 @@ METHOD(child_sa_t, install_outbound, status_t, traffic_selector_t *my_ts, *other_ts; status_t status = SUCCESS; - status = install_internal(this, this->encr_r, this->integ_r, - this->other_spi, this->other_cpi, FALSE, - FALSE, this->tfcv3); - chunk_clear(&this->encr_r); - chunk_clear(&this->integ_r); + if (!(this->outbound_state & CHILD_OUTBOUND_SA)) + { + status = install_internal(this, this->encr_r, this->integ_r, + this->other_spi, this->other_cpi, FALSE, + FALSE, this->tfcv3); + chunk_clear(&this->encr_r); + chunk_clear(&this->integ_r); + } this->outbound_state &= ~CHILD_OUTBOUND_REGISTERED; if (status != SUCCESS) { return status; } - this->outbound_state |= CHILD_OUTBOUND_POLICIES; - if (!this->config->has_option(this->config, OPT_NO_POLICIES)) + if (!this->config->has_option(this->config, OPT_NO_POLICIES) && + !(this->outbound_state & CHILD_OUTBOUND_POLICIES)) { ipsec_sa_cfg_t my_sa, other_sa; uint32_t manual_prio; @@ -1337,6 +1354,7 @@ METHOD(child_sa_t, install_outbound, status_t, } enumerator->destroy(enumerator); } + this->outbound_state |= CHILD_OUTBOUND_POLICIES; return status; } diff --git a/src/libcharon/sa/child_sa.h b/src/libcharon/sa/child_sa.h index e41157e79..082404d93 100644 --- a/src/libcharon/sa/child_sa.h +++ b/src/libcharon/sa/child_sa.h @@ -411,20 +411,23 @@ struct child_sa_t { * Register data for the installation of an outbound SA as responder during * a rekeying. * - * The SA is not installed until install_outbound() is called. + * If the kernel is able to handle SPIs on policies the SA is installed + * immediately, if not it won't be installed until install_outbound() is + * called. * * @param encr encryption key, if any (cloned) * @param integ integrity key (cloned) * @param spi SPI to use, allocated for inbound * @param cpi CPI to use, allocated for outbound * @param tfcv3 TRUE if peer supports ESPv3 TFC + * @return SUCCESS or FAILED */ - void (*register_outbound)(child_sa_t *this, chunk_t encr, chunk_t integ, - uint32_t spi, uint16_t cpi, bool tfcv3); + status_t (*register_outbound)(child_sa_t *this, chunk_t encr, chunk_t integ, + uint32_t spi, uint16_t cpi, bool tfcv3); /** - * Install the outbound SA and the outbound policies as responder during a - * rekeying. + * Install the outbound policies and, if not already done, the outbound SA + * as responder during a rekeying. * * @return SUCCESS or FAILED */ diff --git a/src/libcharon/sa/ikev2/tasks/child_create.c b/src/libcharon/sa/ikev2/tasks/child_create.c index 747b9fac4..9d7d08c3b 100644 --- a/src/libcharon/sa/ikev2/tasks/child_create.c +++ b/src/libcharon/sa/ikev2/tasks/child_create.c @@ -698,9 +698,9 @@ static status_t select_and_install(private_child_create_t *this, status_i = this->child_sa->install(this->child_sa, encr_i, integ_i, this->my_spi, this->my_cpi, this->initiator, TRUE, this->tfcv3); - this->child_sa->register_outbound(this->child_sa, encr_r, integ_r, - this->other_spi, this->other_cpi, this->tfcv3); - status_o = SUCCESS; + status_o = this->child_sa->register_outbound(this->child_sa, encr_r, + integ_r, this->other_spi, this->other_cpi, + this->tfcv3); } } |