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
+113 -48
View File
@@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2006-2017 Tobias Brunner
* Copyright (C) 2016 Andreas Steffen * Copyright (C) 2016 Andreas Steffen
* Copyright (C) 2006-2016 Tobias Brunner
* Copyright (C) 2005-2008 Martin Willi * Copyright (C) 2005-2008 Martin Willi
* Copyright (C) 2006 Daniel Roethlisberger * Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005 Jan Hutter * 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, host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts,
traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa, traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa,
ipsec_sa_cfg_t *other_sa, policy_type_t type, 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, .dst_ts = other_ts,
.mark = this->mark_out, .mark = this->mark_out,
.interface = this->config->get_interface(this->config), .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 = { kernel_ipsec_manage_policy_t out_policy = {
.type = type, .type = type,
@@ -915,23 +944,13 @@ static status_t install_policies_internal(private_child_sa_t *this,
.src = my_addr, .src = my_addr,
.dst = other_addr, .dst = other_addr,
.sa = other_sa, .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_t status = SUCCESS;
status |= charon->kernel->add_policy(charon->kernel, &out_id, &out_policy); 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 /* install an "outbound" FWD policy in case there is a drop policy
* matching outbound forwarded traffic, to allow another tunnel to use * 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 * the reversed subnets and do the same we don't set a reqid (this also
@@ -940,8 +959,6 @@ static status_t install_policies_internal(private_child_sa_t *this,
* policies of two SAs we install them with reduced priority. As they * policies of two SAs we install them with reduced priority. As they
* basically act as bypass policies for drop policies we use a higher * basically act as bypass policies for drop policies we use a higher
* priority than is used for them. */ * priority than is used for them. */
if (this->policies_fwd_out)
{
out_id.dir = POLICY_FWD; out_id.dir = POLICY_FWD;
other_sa->reqid = 0; other_sa->reqid = 0;
if (priority == POLICY_PRIORITY_DEFAULT) if (priority == POLICY_PRIORITY_DEFAULT)
@@ -953,14 +970,66 @@ static status_t install_policies_internal(private_child_sa_t *this,
/* reset the reqid for any other further policies */ /* reset the reqid for any other further policies */
other_sa->reqid = this->reqid; other_sa->reqid = this->reqid;
} }
}
return status; 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, host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts,
traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa, traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa,
ipsec_sa_cfg_t *other_sa, policy_type_t type, 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, .dst_ts = other_ts,
.mark = this->mark_out, .mark = this->mark_out,
.interface = this->config->get_interface(this->config), .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 = { kernel_ipsec_manage_policy_t out_policy = {
.type = type, .type = type,
@@ -985,23 +1049,11 @@ static void del_policies_internal(private_child_sa_t *this,
.src = my_addr, .src = my_addr,
.dst = other_addr, .dst = other_addr,
.sa = other_sa, .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, &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; out_id.dir = POLICY_FWD;
other_sa->reqid = 0; other_sa->reqid = 0;
@@ -1013,6 +1065,20 @@ static void del_policies_internal(private_child_sa_t *this,
other_sa->reqid = this->reqid; 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, METHOD(child_sa_t, add_policies, status_t,
@@ -1077,13 +1143,12 @@ METHOD(child_sa_t, add_policies, status_t,
if (priority == POLICY_PRIORITY_DEFAULT && manual_prio == 0 && if (priority == POLICY_PRIORITY_DEFAULT && manual_prio == 0 &&
require_policy_update()) 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, this->other_addr, my_ts, other_ts,
&my_sa, &other_sa, POLICY_DROP, &my_sa, &other_sa, POLICY_DROP,
POLICY_PRIORITY_FALLBACK, 0); POLICY_PRIORITY_FALLBACK, 0);
} }
/* install policies */
status |= install_policies_internal(this, this->my_addr, status |= install_policies_internal(this, this->my_addr,
this->other_addr, my_ts, other_ts, this->other_addr, my_ts, other_ts,
&my_sa, &other_sa, POLICY_IPSEC, &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 */ /* update fallback policies after the new policy is in place */
if (manual_prio == 0) 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_my_ts ?: my_ts,
old_other_ts ?: other_ts, old_other_ts ?: other_ts,
&my_sa, &other_sa, POLICY_DROP, &my_sa, &other_sa, POLICY_DROP,
POLICY_PRIORITY_FALLBACK, 0); 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, &my_sa, &other_sa, POLICY_DROP,
POLICY_PRIORITY_FALLBACK, 0); POLICY_PRIORITY_FALLBACK, 0);
} }
@@ -1308,7 +1373,7 @@ METHOD(child_sa_t, destroy, void,
if (priority == POLICY_PRIORITY_DEFAULT && manual_prio == 0 && if (priority == POLICY_PRIORITY_DEFAULT && manual_prio == 0 &&
require_policy_update()) 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, my_ts, other_ts, &my_sa, &other_sa,
POLICY_DROP, POLICY_PRIORITY_FALLBACK, 0); POLICY_DROP, POLICY_PRIORITY_FALLBACK, 0);
} }