diff options
Diffstat (limited to 'src/libcharon/sa')
-rw-r--r-- | src/libcharon/sa/child_sa.c | 59 | ||||
-rw-r--r-- | src/libcharon/sa/shunt_manager.c | 4 |
2 files changed, 43 insertions, 20 deletions
diff --git a/src/libcharon/sa/child_sa.c b/src/libcharon/sa/child_sa.c index 05d42ba1d..a1e47a2a4 100644 --- a/src/libcharon/sa/child_sa.c +++ b/src/libcharon/sa/child_sa.c @@ -1,4 +1,5 @@ /* + * Coypright (C) 2016 Andreas Steffen * Copyright (C) 2006-2016 Tobias Brunner * Copyright (C) 2005-2008 Martin Willi * Copyright (C) 2006 Daniel Roethlisberger @@ -881,7 +882,8 @@ static void prepare_sa_cfg(private_child_sa_t *this, ipsec_sa_cfg_t *my_sa, static status_t install_policies_internal(private_child_sa_t *this, host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts, traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa, - ipsec_sa_cfg_t *other_sa, policy_type_t type, policy_priority_t priority) + ipsec_sa_cfg_t *other_sa, policy_type_t type, + policy_priority_t priority, uint32_t manual_prio) { kernel_ipsec_policy_id_t out_id = { .dir = POLICY_OUT, @@ -897,12 +899,14 @@ static status_t install_policies_internal(private_child_sa_t *this, kernel_ipsec_manage_policy_t out_policy = { .type = type, .prio = priority, + .manual_prio = manual_prio, .src = my_addr, .dst = other_addr, .sa = other_sa, }, in_policy = { .type = type, .prio = priority, + .manual_prio = manual_prio, .src = other_addr, .dst = my_addr, .sa = my_sa, @@ -936,7 +940,8 @@ static status_t install_policies_internal(private_child_sa_t *this, static void del_policies_internal(private_child_sa_t *this, host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts, traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa, - ipsec_sa_cfg_t *other_sa, policy_type_t type, policy_priority_t priority) + ipsec_sa_cfg_t *other_sa, policy_type_t type, + policy_priority_t priority, uint32_t manual_prio) { kernel_ipsec_policy_id_t out_id = { .dir = POLICY_OUT, @@ -952,12 +957,14 @@ static void del_policies_internal(private_child_sa_t *this, kernel_ipsec_manage_policy_t out_policy = { .type = type, .prio = priority, + .manual_prio = manual_prio, .src = my_addr, .dst = other_addr, .sa = other_sa, }, in_policy = { .type = type, .prio = priority, + .manual_prio = manual_prio, .src = other_addr, .dst = my_addr, .sa = my_sa, @@ -1019,8 +1026,10 @@ METHOD(child_sa_t, add_policies, status_t, { policy_priority_t priority; 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); /* if we're not in state CHILD_INSTALLING (i.e. if there is no SAD * entry) we install a trap policy */ @@ -1034,18 +1043,20 @@ METHOD(child_sa_t, add_policies, status_t, { /* install outbound drop policy to avoid packets leaving unencrypted * when updating policies */ - if (priority == POLICY_PRIORITY_DEFAULT && require_policy_update()) + if (priority == POLICY_PRIORITY_DEFAULT && manual_prio == 0 && + require_policy_update()) { status |= install_policies_internal(this, this->my_addr, this->other_addr, my_ts, other_ts, &my_sa, &other_sa, POLICY_DROP, - POLICY_PRIORITY_FALLBACK); + POLICY_PRIORITY_FALLBACK, 0); } /* install policies */ status |= install_policies_internal(this, this->my_addr, this->other_addr, my_ts, other_ts, - &my_sa, &other_sa, POLICY_IPSEC, priority); + &my_sa, &other_sa, POLICY_IPSEC, + priority, manual_prio); if (status != SUCCESS) { @@ -1157,18 +1168,21 @@ METHOD(child_sa_t, update, status_t, ipsec_sa_cfg_t my_sa, other_sa; enumerator_t *enumerator; traffic_selector_t *my_ts, *other_ts; + uint32_t manual_prio; prepare_sa_cfg(this, &my_sa, &other_sa); + manual_prio = this->config->get_manual_prio(this->config); /* always use high priorities, as hosts getting updated are INSTALLED */ enumerator = create_policy_enumerator(this); while (enumerator->enumerate(enumerator, &my_ts, &other_ts)) { traffic_selector_t *old_my_ts = NULL, *old_other_ts = NULL; + /* remove old policies first */ del_policies_internal(this, this->my_addr, this->other_addr, - my_ts, other_ts, &my_sa, &other_sa, - POLICY_IPSEC, POLICY_PRIORITY_DEFAULT); + my_ts, other_ts, &my_sa, &other_sa, POLICY_IPSEC, + POLICY_PRIORITY_DEFAULT, manual_prio); /* check if we have to update a "dynamic" traffic selector */ if (!me->ip_equals(me, this->my_addr) && @@ -1191,17 +1205,20 @@ METHOD(child_sa_t, update, status_t, /* reinstall updated policies */ install_policies_internal(this, me, other, my_ts, other_ts, &my_sa, &other_sa, POLICY_IPSEC, - POLICY_PRIORITY_DEFAULT); + POLICY_PRIORITY_DEFAULT, manual_prio); /* update fallback policies after the new policy is in place */ - del_policies_internal(this, this->my_addr, this->other_addr, - old_my_ts ?: my_ts, - old_other_ts ?: other_ts, - &my_sa, &other_sa, POLICY_DROP, - POLICY_PRIORITY_FALLBACK); - install_policies_internal(this, me, other, my_ts, other_ts, + if (manual_prio == 0) + { + del_policies_internal(this, this->my_addr, this->other_addr, + old_my_ts ?: my_ts, + old_other_ts ?: other_ts, + &my_sa, &other_sa, POLICY_DROP, + POLICY_PRIORITY_FALLBACK, 0); + install_policies_internal(this, me, other, my_ts, other_ts, &my_sa, &other_sa, POLICY_DROP, - POLICY_PRIORITY_FALLBACK); + POLICY_PRIORITY_FALLBACK, 0); + } DESTROY_IF(old_my_ts); DESTROY_IF(old_other_ts); } @@ -1244,20 +1261,24 @@ METHOD(child_sa_t, destroy, void, if (this->config->install_policy(this->config)) { 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); /* 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); - if (priority == POLICY_PRIORITY_DEFAULT && require_policy_update()) + my_ts, other_ts, &my_sa, &other_sa, + POLICY_IPSEC, priority, manual_prio); + if (priority == POLICY_PRIORITY_DEFAULT && manual_prio == 0 && + require_policy_update()) { del_policies_internal(this, this->my_addr, this->other_addr, - my_ts, other_ts, &my_sa, &other_sa, POLICY_DROP, - POLICY_PRIORITY_FALLBACK); + my_ts, other_ts, &my_sa, &other_sa, + POLICY_DROP, POLICY_PRIORITY_FALLBACK, 0); } } enumerator->destroy(enumerator); diff --git a/src/libcharon/sa/shunt_manager.c b/src/libcharon/sa/shunt_manager.c index 36af86bae..b74b454ea 100644 --- a/src/libcharon/sa/shunt_manager.c +++ b/src/libcharon/sa/shunt_manager.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Tobias Brunner - * Copyright (C) 2011 Andreas Steffen + * Copyright (C) 2011-2016 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -119,6 +119,7 @@ static bool install_shunt_policy(child_cfg_t *child) kernel_ipsec_manage_policy_t policy = { .type = policy_type, .prio = policy_prio, + .manual_prio = child->get_manual_prio(child), .src = host_any, .dst = host_any, .sa = &sa, @@ -265,6 +266,7 @@ static void uninstall_shunt_policy(child_cfg_t *child) kernel_ipsec_manage_policy_t policy = { .type = policy_type, .prio = policy_prio, + .manual_prio = child->get_manual_prio(child), .src = host_any, .dst = host_any, .sa = &sa, |