child-sa: Split in- and outbound policy de-/installation

Only install outbound fallback policies.
This commit is contained in:
Tobias Brunner
2017-05-23 18:41:30 +02:00
parent b00bcb9add
commit 29ef4cf5f4
+129 -64
View File
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2006-2017 Tobias Brunner
* Copyright (C) 2016 Andreas Steffen
* Copyright (C) 2006-2016 Tobias Brunner
* Copyright (C) 2005-2008 Martin Willi
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005 Jan Hutter
@@ -888,9 +888,43 @@ static void prepare_sa_cfg(private_child_sa_t *this, ipsec_sa_cfg_t *my_sa,
}
/**
* Install 3 policies: out, in and forward
* Install inbound policie(s): in, fwd
*/
static status_t install_policies_internal(private_child_sa_t *this,
static status_t install_policies_inbound(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, uint32_t manual_prio)
{
kernel_ipsec_policy_id_t in_id = {
.dir = POLICY_IN,
.src_ts = other_ts,
.dst_ts = my_ts,
.mark = this->mark_in,
};
kernel_ipsec_manage_policy_t in_policy = {
.type = type,
.prio = priority,
.manual_prio = manual_prio,
.src = other_addr,
.dst = my_addr,
.sa = my_sa,
};
status_t status = SUCCESS;
status |= charon->kernel->add_policy(charon->kernel, &in_id, &in_policy);
if (this->mode != MODE_TRANSPORT)
{
in_id.dir = POLICY_FWD;
status |= charon->kernel->add_policy(charon->kernel, &in_id, &in_policy);
}
return status;
}
/**
* Install outbound policie(s): out, [fwd]
*/
static status_t install_policies_outbound(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,
@@ -902,11 +936,6 @@ static status_t install_policies_internal(private_child_sa_t *this,
.dst_ts = other_ts,
.mark = this->mark_out,
.interface = this->config->get_interface(this->config),
}, in_id = {
.dir = POLICY_IN,
.src_ts = other_ts,
.dst_ts = my_ts,
.mark = this->mark_in,
};
kernel_ipsec_manage_policy_t out_policy = {
.type = type,
@@ -915,23 +944,13 @@ static status_t install_policies_internal(private_child_sa_t *this,
.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,
};
status_t status = SUCCESS;
status |= charon->kernel->add_policy(charon->kernel, &out_id, &out_policy);
status |= charon->kernel->add_policy(charon->kernel, &in_id, &in_policy);
if (this->mode != MODE_TRANSPORT)
{
in_id.dir = POLICY_FWD;
status |= charon->kernel->add_policy(charon->kernel, &in_id, &in_policy);
if (this->mode != MODE_TRANSPORT && this->policies_fwd_out)
{
/* install an "outbound" FWD policy in case there is a drop policy
* matching outbound forwarded traffic, to allow another tunnel to use
* the reversed subnets and do the same we don't set a reqid (this also
@@ -940,27 +959,77 @@ static status_t install_policies_internal(private_child_sa_t *this,
* policies of two SAs we install them with reduced priority. As they
* basically act as bypass policies for drop policies we use a higher
* priority than is used for them. */
if (this->policies_fwd_out)
out_id.dir = POLICY_FWD;
other_sa->reqid = 0;
if (priority == POLICY_PRIORITY_DEFAULT)
{
out_id.dir = POLICY_FWD;
other_sa->reqid = 0;
if (priority == POLICY_PRIORITY_DEFAULT)
{
out_policy.prio = POLICY_PRIORITY_ROUTED;
}
status |= charon->kernel->add_policy(charon->kernel, &out_id,
&out_policy);
/* reset the reqid for any other further policies */
other_sa->reqid = this->reqid;
out_policy.prio = POLICY_PRIORITY_ROUTED;
}
status |= charon->kernel->add_policy(charon->kernel, &out_id,
&out_policy);
/* reset the reqid for any other further policies */
other_sa->reqid = this->reqid;
}
return status;
}
/**
* Delete 3 policies: out, in and forward
* Install all policies
*/
static void del_policies_internal(private_child_sa_t *this,
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, uint32_t manual_prio)
{
status_t status = SUCCESS;
status |= install_policies_inbound(this, my_addr, other_addr, my_ts,
other_ts, my_sa, other_sa, type,
priority, manual_prio);
status |= install_policies_outbound(this, my_addr, other_addr, my_ts,
other_ts, my_sa, other_sa, type,
priority, manual_prio);
return status;
}
/**
* Delete inbound policies: in, fwd
*/
static void del_policies_inbound(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, uint32_t manual_prio)
{
kernel_ipsec_policy_id_t in_id = {
.dir = POLICY_IN,
.src_ts = other_ts,
.dst_ts = my_ts,
.mark = this->mark_in,
};
kernel_ipsec_manage_policy_t in_policy = {
.type = type,
.prio = priority,
.manual_prio = manual_prio,
.src = other_addr,
.dst = my_addr,
.sa = my_sa,
};
charon->kernel->del_policy(charon->kernel, &in_id, &in_policy);
if (this->mode != MODE_TRANSPORT)
{
in_id.dir = POLICY_FWD;
charon->kernel->del_policy(charon->kernel, &in_id, &in_policy);
}
}
/**
* Delete outbound policies: out, [fwd]
*/
static void del_policies_outbound(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,
@@ -972,11 +1041,6 @@ static void del_policies_internal(private_child_sa_t *this,
.dst_ts = other_ts,
.mark = this->mark_out,
.interface = this->config->get_interface(this->config),
}, in_id = {
.dir = POLICY_IN,
.src_ts = other_ts,
.dst_ts = my_ts,
.mark = this->mark_in,
};
kernel_ipsec_manage_policy_t out_policy = {
.type = type,
@@ -985,36 +1049,38 @@ static void del_policies_internal(private_child_sa_t *this,
.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,
};
charon->kernel->del_policy(charon->kernel, &out_id, &out_policy);
charon->kernel->del_policy(charon->kernel, &in_id, &in_policy);
if (this->mode != MODE_TRANSPORT)
{
in_id.dir = POLICY_FWD;
charon->kernel->del_policy(charon->kernel, &in_id, &in_policy);
if (this->policies_fwd_out)
if (this->mode != MODE_TRANSPORT && this->policies_fwd_out)
{
out_id.dir = POLICY_FWD;
other_sa->reqid = 0;
if (priority == POLICY_PRIORITY_DEFAULT)
{
out_id.dir = POLICY_FWD;
other_sa->reqid = 0;
if (priority == POLICY_PRIORITY_DEFAULT)
{
out_policy.prio = POLICY_PRIORITY_ROUTED;
}
charon->kernel->del_policy(charon->kernel, &out_id, &out_policy);
other_sa->reqid = this->reqid;
out_policy.prio = POLICY_PRIORITY_ROUTED;
}
charon->kernel->del_policy(charon->kernel, &out_id, &out_policy);
other_sa->reqid = this->reqid;
}
}
/**
* Delete in- and outbound policies
*/
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, uint32_t manual_prio)
{
del_policies_outbound(this, my_addr, other_addr, my_ts, other_ts, my_sa,
other_sa, type, priority, manual_prio);
del_policies_inbound(this, my_addr, other_addr, my_ts, other_ts, my_sa,
other_sa, type, priority, manual_prio);
}
METHOD(child_sa_t, add_policies, status_t,
private_child_sa_t *this, linked_list_t *my_ts_list,
linked_list_t *other_ts_list)
@@ -1077,13 +1143,12 @@ METHOD(child_sa_t, add_policies, status_t,
if (priority == POLICY_PRIORITY_DEFAULT && manual_prio == 0 &&
require_policy_update())
{
status |= install_policies_internal(this, this->my_addr,
status |= install_policies_outbound(this, this->my_addr,
this->other_addr, my_ts, other_ts,
&my_sa, &other_sa, POLICY_DROP,
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,
@@ -1242,12 +1307,12 @@ METHOD(child_sa_t, update, status_t,
/* update fallback policies after the new policy is in place */
if (manual_prio == 0)
{
del_policies_internal(this, this->my_addr, this->other_addr,
del_policies_outbound(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,
install_policies_outbound(this, me, other, my_ts, other_ts,
&my_sa, &other_sa, POLICY_DROP,
POLICY_PRIORITY_FALLBACK, 0);
}
@@ -1308,7 +1373,7 @@ METHOD(child_sa_t, destroy, void,
if (priority == POLICY_PRIORITY_DEFAULT && manual_prio == 0 &&
require_policy_update())
{
del_policies_internal(this, this->my_addr, this->other_addr,
del_policies_outbound(this, this->my_addr, this->other_addr,
my_ts, other_ts, &my_sa, &other_sa,
POLICY_DROP, POLICY_PRIORITY_FALLBACK, 0);
}