From: Tobias Brunner Date: Mon, 20 Mar 2017 12:35:56 +0000 (+0100) Subject: child-sa: Add method to remove the outbound SA and policies X-Git-Tag: 5.5.3~25^2~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c5fed4cdeee65dd44b5a6f968871d5ae64dbf10e;p=thirdparty%2Fstrongswan.git child-sa: Add method to remove the outbound SA and policies --- diff --git a/src/libcharon/sa/child_sa.c b/src/libcharon/sa/child_sa.c index a5d172dc63..bd106f232b 100644 --- a/src/libcharon/sa/child_sa.c +++ b/src/libcharon/sa/child_sa.c @@ -1317,6 +1317,64 @@ METHOD(child_sa_t, install_outbound, status_t, return status; } +METHOD(child_sa_t, remove_outbound, void, + private_child_sa_t *this) +{ + enumerator_t *enumerator; + traffic_selector_t *my_ts, *other_ts; + + switch (this->outbound_state) + { + case OUTBOUND_INSTALLED: + break; + case OUTBOUND_REGISTERED: + chunk_clear(&this->encr_r); + chunk_clear(&this->integ_r); + this->outbound_state = OUTBOUND_NONE; + /* fall-through */ + case OUTBOUND_NONE: + return; + } + + if (!this->config->has_option(this->config, OPT_NO_POLICIES)) + { + ipsec_sa_cfg_t my_sa, other_sa; + uint32_t manual_prio; + + prepare_sa_cfg(this, &my_sa, &other_sa); + manual_prio = this->config->get_manual_prio(this->config); + + enumerator = create_policy_enumerator(this); + while (enumerator->enumerate(enumerator, &my_ts, &other_ts)) + { + del_policies_outbound(this, this->my_addr, this->other_addr, + my_ts, other_ts, &my_sa, &other_sa, + POLICY_IPSEC, POLICY_PRIORITY_DEFAULT, + manual_prio); + if (manual_prio == 0 && require_policy_update()) + { + del_policies_outbound(this, this->my_addr, this->other_addr, + my_ts, other_ts, &my_sa, &other_sa, + POLICY_DROP, POLICY_PRIORITY_FALLBACK, 0); + } + } + enumerator->destroy(enumerator); + } + + kernel_ipsec_sa_id_t id = { + .src = this->my_addr, + .dst = this->other_addr, + .spi = this->other_spi, + .proto = proto_ike2ip(this->protocol), + .mark = this->mark_out, + }; + kernel_ipsec_del_sa_t sa = { + .cpi = this->other_cpi, + }; + charon->kernel->del_sa(charon->kernel, &id, &sa); + this->outbound_state = OUTBOUND_NONE; +} + METHOD(child_sa_t, set_rekey_spi, void, private_child_sa_t *this, uint32_t spi) { @@ -1519,19 +1577,28 @@ METHOD(child_sa_t, destroy, void, { ipsec_sa_cfg_t my_sa, other_sa; uint32_t manual_prio; + bool del_outbound; prepare_sa_cfg(this, &my_sa, &other_sa); manual_prio = this->config->get_manual_prio(this->config); + del_outbound = this->trap || this->outbound_state == OUTBOUND_INSTALLED; /* delete all policies in the kernel */ enumerator = create_policy_enumerator(this); while (enumerator->enumerate(enumerator, &my_ts, &other_ts)) { - del_policies_internal(this, this->my_addr, this->other_addr, - my_ts, other_ts, &my_sa, &other_sa, - POLICY_IPSEC, priority, manual_prio); - if (priority == POLICY_PRIORITY_DEFAULT && manual_prio == 0 && - require_policy_update()) + if (del_outbound) + { + del_policies_outbound(this, this->my_addr, + this->other_addr, my_ts, other_ts, + &my_sa, &other_sa, POLICY_IPSEC, + priority, manual_prio); + } + del_policies_inbound(this, this->my_addr, this->other_addr, + my_ts, other_ts, &my_sa, &other_sa, + POLICY_IPSEC, priority, manual_prio); + if (!this->trap && manual_prio == 0 && require_policy_update() && + del_outbound) { del_policies_outbound(this, this->my_addr, this->other_addr, my_ts, other_ts, &my_sa, &other_sa, @@ -1668,6 +1735,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other, .install = _install, .register_outbound = _register_outbound, .install_outbound = _install_outbound, + .remove_outbound = _remove_outbound, .set_rekey_spi = _set_rekey_spi, .get_rekey_spi = _get_rekey_spi, .update = _update, diff --git a/src/libcharon/sa/child_sa.h b/src/libcharon/sa/child_sa.h index 4483346b1c..06c84d5641 100644 --- a/src/libcharon/sa/child_sa.h +++ b/src/libcharon/sa/child_sa.h @@ -390,6 +390,11 @@ struct child_sa_t { */ status_t (*install_outbound)(child_sa_t *this); + /** + * Remove the outbound SA and the outbound policies after a rekeying. + */ + void (*remove_outbound)(child_sa_t *this); + /** * Configure the policies using some traffic selectors. *