Merge branch 'fwd-out-policies-optional'
This makes the FWD policies in the out direction optional (disabled by default). They may be enabled (e.g. if conflicting drop policies are used) via the policies_fwd_out swanctl.conf option.
This commit is contained in:
@@ -153,6 +153,11 @@ struct private_child_cfg_t {
|
|||||||
*/
|
*/
|
||||||
bool install_policy;
|
bool install_policy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install outbound FWD policies
|
||||||
|
*/
|
||||||
|
bool fwd_out_policy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* anti-replay window size
|
* anti-replay window size
|
||||||
*/
|
*/
|
||||||
@@ -564,6 +569,12 @@ METHOD(child_cfg_t, install_policy, bool,
|
|||||||
return this->install_policy;
|
return this->install_policy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(child_cfg_t, install_fwd_out_policy, bool,
|
||||||
|
private_child_cfg_t *this)
|
||||||
|
{
|
||||||
|
return this->fwd_out_policy;
|
||||||
|
}
|
||||||
|
|
||||||
#define LT_PART_EQUALS(a, b) ({ a.life == b.life && a.rekey == b.rekey && a.jitter == b.jitter; })
|
#define LT_PART_EQUALS(a, b) ({ a.life == b.life && a.rekey == b.rekey && a.jitter == b.jitter; })
|
||||||
#define LIFETIME_EQUALS(a, b) ({ LT_PART_EQUALS(a.time, b.time) && LT_PART_EQUALS(a.bytes, b.bytes) && LT_PART_EQUALS(a.packets, b.packets); })
|
#define LIFETIME_EQUALS(a, b) ({ LT_PART_EQUALS(a.time, b.time) && LT_PART_EQUALS(a.bytes, b.bytes) && LT_PART_EQUALS(a.packets, b.packets); })
|
||||||
|
|
||||||
@@ -613,6 +624,7 @@ METHOD(child_cfg_t, equals, bool,
|
|||||||
this->replay_window == other->replay_window &&
|
this->replay_window == other->replay_window &&
|
||||||
this->proxy_mode == other->proxy_mode &&
|
this->proxy_mode == other->proxy_mode &&
|
||||||
this->install_policy == other->install_policy &&
|
this->install_policy == other->install_policy &&
|
||||||
|
this->fwd_out_policy == other->fwd_out_policy &&
|
||||||
streq(this->updown, other->updown) &&
|
streq(this->updown, other->updown) &&
|
||||||
streq(this->interface, other->interface);
|
streq(this->interface, other->interface);
|
||||||
}
|
}
|
||||||
@@ -673,6 +685,7 @@ child_cfg_t *child_cfg_create(char *name, child_cfg_create_t *data)
|
|||||||
.set_replay_window = _set_replay_window,
|
.set_replay_window = _set_replay_window,
|
||||||
.use_proxy_mode = _use_proxy_mode,
|
.use_proxy_mode = _use_proxy_mode,
|
||||||
.install_policy = _install_policy,
|
.install_policy = _install_policy,
|
||||||
|
.install_fwd_out_policy = _install_fwd_out_policy,
|
||||||
.equals = _equals,
|
.equals = _equals,
|
||||||
.get_ref = _get_ref,
|
.get_ref = _get_ref,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
@@ -695,6 +708,7 @@ child_cfg_t *child_cfg_create(char *name, child_cfg_create_t *data)
|
|||||||
.manual_prio = data->priority,
|
.manual_prio = data->priority,
|
||||||
.interface = strdupnull(data->interface),
|
.interface = strdupnull(data->interface),
|
||||||
.install_policy = !data->suppress_policies,
|
.install_policy = !data->suppress_policies,
|
||||||
|
.fwd_out_policy = data->fwd_out_policies,
|
||||||
.refcount = 1,
|
.refcount = 1,
|
||||||
.proposals = linked_list_create(),
|
.proposals = linked_list_create(),
|
||||||
.my_ts = linked_list_create(),
|
.my_ts = linked_list_create(),
|
||||||
|
|||||||
@@ -283,6 +283,14 @@ struct child_cfg_t {
|
|||||||
*/
|
*/
|
||||||
bool (*install_policy)(child_cfg_t *this);
|
bool (*install_policy)(child_cfg_t *this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether outbound FWD IPsec policies should be installed.
|
||||||
|
*
|
||||||
|
* @return TRUE, if outbound FWD policies should be installed
|
||||||
|
* FALSE, otherwise
|
||||||
|
*/
|
||||||
|
bool (*install_fwd_out_policy)(child_cfg_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if two child_cfg objects are equal.
|
* Check if two child_cfg objects are equal.
|
||||||
*
|
*
|
||||||
@@ -346,6 +354,8 @@ struct child_cfg_create_t {
|
|||||||
bool hostaccess;
|
bool hostaccess;
|
||||||
/** Don't install IPsec policies */
|
/** Don't install IPsec policies */
|
||||||
bool suppress_policies;
|
bool suppress_policies;
|
||||||
|
/** Install outbound FWD IPsec policies to bypass drop policies */
|
||||||
|
bool fwd_out_policies;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -437,6 +437,7 @@ typedef struct {
|
|||||||
linked_list_t *remote_ts;
|
linked_list_t *remote_ts;
|
||||||
uint32_t replay_window;
|
uint32_t replay_window;
|
||||||
bool policies;
|
bool policies;
|
||||||
|
bool policies_fwd_out;
|
||||||
child_cfg_create_t cfg;
|
child_cfg_create_t cfg;
|
||||||
} child_data_t;
|
} child_data_t;
|
||||||
|
|
||||||
@@ -462,6 +463,7 @@ static void log_child_data(child_data_t *data, char *name)
|
|||||||
DBG2(DBG_CFG, " ipcomp = %u", cfg->ipcomp);
|
DBG2(DBG_CFG, " ipcomp = %u", cfg->ipcomp);
|
||||||
DBG2(DBG_CFG, " mode = %N", ipsec_mode_names, cfg->mode);
|
DBG2(DBG_CFG, " mode = %N", ipsec_mode_names, cfg->mode);
|
||||||
DBG2(DBG_CFG, " policies = %u", data->policies);
|
DBG2(DBG_CFG, " policies = %u", data->policies);
|
||||||
|
DBG2(DBG_CFG, " policies_fwd_out = %u", data->policies_fwd_out);
|
||||||
if (data->replay_window != REPLAY_UNDEFINED)
|
if (data->replay_window != REPLAY_UNDEFINED)
|
||||||
{
|
{
|
||||||
DBG2(DBG_CFG, " replay_window = %u", data->replay_window);
|
DBG2(DBG_CFG, " replay_window = %u", data->replay_window);
|
||||||
@@ -1330,31 +1332,32 @@ CALLBACK(child_kv, bool,
|
|||||||
child_data_t *child, vici_message_t *message, char *name, chunk_t value)
|
child_data_t *child, vici_message_t *message, char *name, chunk_t value)
|
||||||
{
|
{
|
||||||
parse_rule_t rules[] = {
|
parse_rule_t rules[] = {
|
||||||
{ "updown", parse_string, &child->cfg.updown },
|
{ "updown", parse_string, &child->cfg.updown },
|
||||||
{ "hostaccess", parse_bool, &child->cfg.hostaccess },
|
{ "hostaccess", parse_bool, &child->cfg.hostaccess },
|
||||||
{ "mode", parse_mode, &child->cfg.mode },
|
{ "mode", parse_mode, &child->cfg.mode },
|
||||||
{ "policies", parse_bool, &child->policies },
|
{ "policies", parse_bool, &child->policies },
|
||||||
{ "replay_window", parse_uint32, &child->replay_window },
|
{ "policies_fwd_out", parse_bool, &child->policies_fwd_out },
|
||||||
{ "rekey_time", parse_time, &child->cfg.lifetime.time.rekey },
|
{ "replay_window", parse_uint32, &child->replay_window },
|
||||||
{ "life_time", parse_time, &child->cfg.lifetime.time.life },
|
{ "rekey_time", parse_time, &child->cfg.lifetime.time.rekey },
|
||||||
{ "rand_time", parse_time, &child->cfg.lifetime.time.jitter },
|
{ "life_time", parse_time, &child->cfg.lifetime.time.life },
|
||||||
{ "rekey_bytes", parse_bytes, &child->cfg.lifetime.bytes.rekey },
|
{ "rand_time", parse_time, &child->cfg.lifetime.time.jitter },
|
||||||
{ "life_bytes", parse_bytes, &child->cfg.lifetime.bytes.life },
|
{ "rekey_bytes", parse_bytes, &child->cfg.lifetime.bytes.rekey },
|
||||||
{ "rand_bytes", parse_bytes, &child->cfg.lifetime.bytes.jitter },
|
{ "life_bytes", parse_bytes, &child->cfg.lifetime.bytes.life },
|
||||||
{ "rekey_packets", parse_uint64, &child->cfg.lifetime.packets.rekey },
|
{ "rand_bytes", parse_bytes, &child->cfg.lifetime.bytes.jitter },
|
||||||
{ "life_packets", parse_uint64, &child->cfg.lifetime.packets.life },
|
{ "rekey_packets", parse_uint64, &child->cfg.lifetime.packets.rekey },
|
||||||
{ "rand_packets", parse_uint64, &child->cfg.lifetime.packets.jitter },
|
{ "life_packets", parse_uint64, &child->cfg.lifetime.packets.life },
|
||||||
{ "dpd_action", parse_action, &child->cfg.dpd_action },
|
{ "rand_packets", parse_uint64, &child->cfg.lifetime.packets.jitter },
|
||||||
{ "start_action", parse_action, &child->cfg.start_action },
|
{ "dpd_action", parse_action, &child->cfg.dpd_action },
|
||||||
{ "close_action", parse_action, &child->cfg.close_action },
|
{ "start_action", parse_action, &child->cfg.start_action },
|
||||||
{ "ipcomp", parse_bool, &child->cfg.ipcomp },
|
{ "close_action", parse_action, &child->cfg.close_action },
|
||||||
{ "inactivity", parse_time, &child->cfg.inactivity },
|
{ "ipcomp", parse_bool, &child->cfg.ipcomp },
|
||||||
{ "reqid", parse_uint32, &child->cfg.reqid },
|
{ "inactivity", parse_time, &child->cfg.inactivity },
|
||||||
{ "mark_in", parse_mark, &child->cfg.mark_in },
|
{ "reqid", parse_uint32, &child->cfg.reqid },
|
||||||
{ "mark_out", parse_mark, &child->cfg.mark_out },
|
{ "mark_in", parse_mark, &child->cfg.mark_in },
|
||||||
{ "tfc_padding", parse_tfc, &child->cfg.tfc },
|
{ "mark_out", parse_mark, &child->cfg.mark_out },
|
||||||
{ "priority", parse_uint32, &child->cfg.priority },
|
{ "tfc_padding", parse_tfc, &child->cfg.tfc },
|
||||||
{ "interface", parse_string, &child->cfg.interface },
|
{ "priority", parse_uint32, &child->cfg.priority },
|
||||||
|
{ "interface", parse_string, &child->cfg.interface },
|
||||||
};
|
};
|
||||||
|
|
||||||
return parse_rules(rules, countof(rules), name, value,
|
return parse_rules(rules, countof(rules), name, value,
|
||||||
@@ -1537,6 +1540,7 @@ CALLBACK(children_sn, bool,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
child.cfg.suppress_policies = !child.policies;
|
child.cfg.suppress_policies = !child.policies;
|
||||||
|
child.cfg.fwd_out_policies = child.policies_fwd_out;
|
||||||
|
|
||||||
check_lifetimes(&child.cfg.lifetime);
|
check_lifetimes(&child.cfg.lifetime);
|
||||||
|
|
||||||
|
|||||||
+27
-14
@@ -111,11 +111,16 @@ struct private_child_sa_t {
|
|||||||
*/
|
*/
|
||||||
bool static_reqid;
|
bool static_reqid;
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Unique CHILD_SA identifier
|
* Unique CHILD_SA identifier
|
||||||
*/
|
*/
|
||||||
uint32_t unique_id;
|
uint32_t unique_id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether FWD policieis in the outbound direction should be installed
|
||||||
|
*/
|
||||||
|
bool policies_fwd_out;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* inbound mark used for this child_sa
|
* inbound mark used for this child_sa
|
||||||
*/
|
*/
|
||||||
@@ -931,15 +936,19 @@ 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. */
|
||||||
out_id.dir = POLICY_FWD;
|
if (this->policies_fwd_out)
|
||||||
other_sa->reqid = 0;
|
|
||||||
if (priority == POLICY_PRIORITY_DEFAULT)
|
|
||||||
{
|
{
|
||||||
out_policy.prio = POLICY_PRIORITY_ROUTED;
|
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;
|
||||||
}
|
}
|
||||||
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;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -988,14 +997,17 @@ static void del_policies_internal(private_child_sa_t *this,
|
|||||||
in_id.dir = POLICY_FWD;
|
in_id.dir = POLICY_FWD;
|
||||||
charon->kernel->del_policy(charon->kernel, &in_id, &in_policy);
|
charon->kernel->del_policy(charon->kernel, &in_id, &in_policy);
|
||||||
|
|
||||||
out_id.dir = POLICY_FWD;
|
if (this->policies_fwd_out)
|
||||||
other_sa->reqid = 0;
|
|
||||||
if (priority == POLICY_PRIORITY_DEFAULT)
|
|
||||||
{
|
{
|
||||||
out_policy.prio = POLICY_PRIORITY_ROUTED;
|
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;
|
||||||
}
|
}
|
||||||
charon->kernel->del_policy(charon->kernel, &out_id, &out_policy);
|
|
||||||
other_sa->reqid = this->reqid;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1443,6 +1455,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
|
|||||||
.mark_in = config->get_mark(config, TRUE),
|
.mark_in = config->get_mark(config, TRUE),
|
||||||
.mark_out = config->get_mark(config, FALSE),
|
.mark_out = config->get_mark(config, FALSE),
|
||||||
.install_time = time_monotonic(NULL),
|
.install_time = time_monotonic(NULL),
|
||||||
|
.policies_fwd_out = config->install_fwd_out_policy(config),
|
||||||
);
|
);
|
||||||
|
|
||||||
this->config = config;
|
this->config = config;
|
||||||
|
|||||||
@@ -659,6 +659,13 @@ connections.<conn>.children.<child>.policies = yes
|
|||||||
Whether to install IPsec policies or not. Disabling this can be useful in
|
Whether to install IPsec policies or not. Disabling this can be useful in
|
||||||
some scenarios e.g. MIPv6, where policies are not managed by the IKE daemon.
|
some scenarios e.g. MIPv6, where policies are not managed by the IKE daemon.
|
||||||
|
|
||||||
|
connections.<conn>.children.<child>.policies_fwd_out = no
|
||||||
|
Whether to install outbound FWD IPsec policies or not.
|
||||||
|
|
||||||
|
Whether to install outbound FWD IPsec policies or not. Enabling this is
|
||||||
|
required in case there is a drop policy that would match and block forwarded
|
||||||
|
traffic for this CHILD_SA.
|
||||||
|
|
||||||
connections.<conn>.children.<child>.dpd_action = clear
|
connections.<conn>.children.<child>.dpd_action = clear
|
||||||
Action to perform on DPD timeout (_clear_, _trap_ or _restart_).
|
Action to perform on DPD timeout (_clear_, _trap_ or _restart_).
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ connections {
|
|||||||
local_ts = 10.1.0.0/16
|
local_ts = 10.1.0.0/16
|
||||||
priority = 2
|
priority = 2
|
||||||
interface = eth0
|
interface = eth0
|
||||||
|
policies_fwd_out = yes
|
||||||
|
|
||||||
esp_proposals = aes128gcm128-modp3072
|
esp_proposals = aes128gcm128-modp3072
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -32,15 +33,15 @@ connections {
|
|||||||
local_ts = 0.0.0.0/0
|
local_ts = 0.0.0.0/0
|
||||||
remote_ts = 0.0.0.0/0
|
remote_ts = 0.0.0.0/0
|
||||||
interface = eth0
|
interface = eth0
|
||||||
priority = 4
|
priority = 4
|
||||||
|
|
||||||
mode = drop
|
mode = drop
|
||||||
start_action = trap
|
start_action = trap
|
||||||
}
|
}
|
||||||
pass-ssh-in {
|
pass-ssh-in {
|
||||||
local_ts = 0.0.0.0/0[tcp/ssh]
|
local_ts = 0.0.0.0/0[tcp/ssh]
|
||||||
remote_ts = 0.0.0.0/0[tcp]
|
remote_ts = 0.0.0.0/0[tcp]
|
||||||
priority = 1
|
priority = 1
|
||||||
|
|
||||||
mode = pass
|
mode = pass
|
||||||
start_action = trap
|
start_action = trap
|
||||||
@@ -61,6 +62,6 @@ connections {
|
|||||||
mode = pass
|
mode = pass
|
||||||
start_action = trap
|
start_action = trap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user