diff options
author | Tobias Brunner <tobias@strongswan.org> | 2016-09-28 17:57:57 +0200 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2016-09-28 17:59:21 +0200 |
commit | 21c898a1f96b6e45f4470f52fb25b9d168395691 (patch) | |
tree | c73d47afc7df93f21201521ec2b56e9ed34e6cd1 /src | |
parent | 175d78df607d985de8033893368ac27e5e003883 (diff) | |
parent | ad1b53454e782e6f310fd3dba25936ffc22ed321 (diff) | |
download | strongswan-21c898a1f96b6e45f4470f52fb25b9d168395691.tar.bz2 strongswan-21c898a1f96b6e45f4470f52fb25b9d168395691.tar.xz |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/libcharon/config/child_cfg.c | 14 | ||||
-rw-r--r-- | src/libcharon/config/child_cfg.h | 10 | ||||
-rw-r--r-- | src/libcharon/plugins/vici/vici_config.c | 54 | ||||
-rw-r--r-- | src/libcharon/sa/child_sa.c | 41 | ||||
-rw-r--r-- | src/swanctl/swanctl.opt | 7 |
5 files changed, 87 insertions, 39 deletions
diff --git a/src/libcharon/config/child_cfg.c b/src/libcharon/config/child_cfg.c index 76d7f2c58..6a9c342f4 100644 --- a/src/libcharon/config/child_cfg.c +++ b/src/libcharon/config/child_cfg.c @@ -154,6 +154,11 @@ struct private_child_cfg_t { bool install_policy; /** + * Install outbound FWD policies + */ + bool fwd_out_policy; + + /** * anti-replay window size */ uint32_t replay_window; @@ -564,6 +569,12 @@ METHOD(child_cfg_t, install_policy, bool, 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 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->proxy_mode == other->proxy_mode && this->install_policy == other->install_policy && + this->fwd_out_policy == other->fwd_out_policy && streq(this->updown, other->updown) && 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, .use_proxy_mode = _use_proxy_mode, .install_policy = _install_policy, + .install_fwd_out_policy = _install_fwd_out_policy, .equals = _equals, .get_ref = _get_ref, .destroy = _destroy, @@ -695,6 +708,7 @@ child_cfg_t *child_cfg_create(char *name, child_cfg_create_t *data) .manual_prio = data->priority, .interface = strdupnull(data->interface), .install_policy = !data->suppress_policies, + .fwd_out_policy = data->fwd_out_policies, .refcount = 1, .proposals = linked_list_create(), .my_ts = linked_list_create(), diff --git a/src/libcharon/config/child_cfg.h b/src/libcharon/config/child_cfg.h index e736b2737..b85bfd9bc 100644 --- a/src/libcharon/config/child_cfg.h +++ b/src/libcharon/config/child_cfg.h @@ -284,6 +284,14 @@ struct child_cfg_t { 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. * * @param other candidate to check for equality against this @@ -346,6 +354,8 @@ struct child_cfg_create_t { bool hostaccess; /** Don't install IPsec policies */ bool suppress_policies; + /** Install outbound FWD IPsec policies to bypass drop policies */ + bool fwd_out_policies; }; /** diff --git a/src/libcharon/plugins/vici/vici_config.c b/src/libcharon/plugins/vici/vici_config.c index daefcaae5..224a51923 100644 --- a/src/libcharon/plugins/vici/vici_config.c +++ b/src/libcharon/plugins/vici/vici_config.c @@ -437,6 +437,7 @@ typedef struct { linked_list_t *remote_ts; uint32_t replay_window; bool policies; + bool policies_fwd_out; child_cfg_create_t cfg; } 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, " mode = %N", ipsec_mode_names, cfg->mode); DBG2(DBG_CFG, " policies = %u", data->policies); + DBG2(DBG_CFG, " policies_fwd_out = %u", data->policies_fwd_out); if (data->replay_window != REPLAY_UNDEFINED) { 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) { parse_rule_t rules[] = { - { "updown", parse_string, &child->cfg.updown }, - { "hostaccess", parse_bool, &child->cfg.hostaccess }, - { "mode", parse_mode, &child->cfg.mode }, - { "policies", parse_bool, &child->policies }, - { "replay_window", parse_uint32, &child->replay_window }, - { "rekey_time", parse_time, &child->cfg.lifetime.time.rekey }, - { "life_time", parse_time, &child->cfg.lifetime.time.life }, - { "rand_time", parse_time, &child->cfg.lifetime.time.jitter }, - { "rekey_bytes", parse_bytes, &child->cfg.lifetime.bytes.rekey }, - { "life_bytes", parse_bytes, &child->cfg.lifetime.bytes.life }, - { "rand_bytes", parse_bytes, &child->cfg.lifetime.bytes.jitter }, - { "rekey_packets", parse_uint64, &child->cfg.lifetime.packets.rekey }, - { "life_packets", parse_uint64, &child->cfg.lifetime.packets.life }, - { "rand_packets", parse_uint64, &child->cfg.lifetime.packets.jitter }, - { "dpd_action", parse_action, &child->cfg.dpd_action }, - { "start_action", parse_action, &child->cfg.start_action }, - { "close_action", parse_action, &child->cfg.close_action }, - { "ipcomp", parse_bool, &child->cfg.ipcomp }, - { "inactivity", parse_time, &child->cfg.inactivity }, - { "reqid", parse_uint32, &child->cfg.reqid }, - { "mark_in", parse_mark, &child->cfg.mark_in }, - { "mark_out", parse_mark, &child->cfg.mark_out }, - { "tfc_padding", parse_tfc, &child->cfg.tfc }, - { "priority", parse_uint32, &child->cfg.priority }, - { "interface", parse_string, &child->cfg.interface }, + { "updown", parse_string, &child->cfg.updown }, + { "hostaccess", parse_bool, &child->cfg.hostaccess }, + { "mode", parse_mode, &child->cfg.mode }, + { "policies", parse_bool, &child->policies }, + { "policies_fwd_out", parse_bool, &child->policies_fwd_out }, + { "replay_window", parse_uint32, &child->replay_window }, + { "rekey_time", parse_time, &child->cfg.lifetime.time.rekey }, + { "life_time", parse_time, &child->cfg.lifetime.time.life }, + { "rand_time", parse_time, &child->cfg.lifetime.time.jitter }, + { "rekey_bytes", parse_bytes, &child->cfg.lifetime.bytes.rekey }, + { "life_bytes", parse_bytes, &child->cfg.lifetime.bytes.life }, + { "rand_bytes", parse_bytes, &child->cfg.lifetime.bytes.jitter }, + { "rekey_packets", parse_uint64, &child->cfg.lifetime.packets.rekey }, + { "life_packets", parse_uint64, &child->cfg.lifetime.packets.life }, + { "rand_packets", parse_uint64, &child->cfg.lifetime.packets.jitter }, + { "dpd_action", parse_action, &child->cfg.dpd_action }, + { "start_action", parse_action, &child->cfg.start_action }, + { "close_action", parse_action, &child->cfg.close_action }, + { "ipcomp", parse_bool, &child->cfg.ipcomp }, + { "inactivity", parse_time, &child->cfg.inactivity }, + { "reqid", parse_uint32, &child->cfg.reqid }, + { "mark_in", parse_mark, &child->cfg.mark_in }, + { "mark_out", parse_mark, &child->cfg.mark_out }, + { "tfc_padding", parse_tfc, &child->cfg.tfc }, + { "priority", parse_uint32, &child->cfg.priority }, + { "interface", parse_string, &child->cfg.interface }, }; return parse_rules(rules, countof(rules), name, value, @@ -1537,6 +1540,7 @@ CALLBACK(children_sn, bool, } } child.cfg.suppress_policies = !child.policies; + child.cfg.fwd_out_policies = child.policies_fwd_out; check_lifetimes(&child.cfg.lifetime); diff --git a/src/libcharon/sa/child_sa.c b/src/libcharon/sa/child_sa.c index 8a405d93c..e4364de12 100644 --- a/src/libcharon/sa/child_sa.c +++ b/src/libcharon/sa/child_sa.c @@ -111,12 +111,17 @@ struct private_child_sa_t { */ bool static_reqid; - /* + /** * Unique CHILD_SA identifier */ 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 */ mark_t mark_in; @@ -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 * basically act as bypass policies for drop policies we use a higher * priority than is used for them. */ - out_id.dir = POLICY_FWD; - other_sa->reqid = 0; - if (priority == POLICY_PRIORITY_DEFAULT) + if (this->policies_fwd_out) { - 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; } @@ -988,14 +997,17 @@ static void del_policies_internal(private_child_sa_t *this, in_id.dir = POLICY_FWD; charon->kernel->del_policy(charon->kernel, &in_id, &in_policy); - out_id.dir = POLICY_FWD; - other_sa->reqid = 0; - if (priority == POLICY_PRIORITY_DEFAULT) + if (this->policies_fwd_out) { - 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_out = config->get_mark(config, FALSE), .install_time = time_monotonic(NULL), + .policies_fwd_out = config->install_fwd_out_policy(config), ); this->config = config; diff --git a/src/swanctl/swanctl.opt b/src/swanctl/swanctl.opt index 15cbc6cfc..2a4f5a789 100644 --- a/src/swanctl/swanctl.opt +++ b/src/swanctl/swanctl.opt @@ -659,6 +659,13 @@ connections.<conn>.children.<child>.policies = yes 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. +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 Action to perform on DPD timeout (_clear_, _trap_ or _restart_). |