/*
- * Copyright (C) 2006-2018 Tobias Brunner
+ * Copyright (C) 2006-2019 Tobias Brunner
* Copyright (C) 2016 Andreas Steffen
* Copyright (C) 2005-2008 Martin Willi
* Copyright (C) 2006 Daniel Roethlisberger
*/
bool policies_fwd_out;
+ /**
+ * Inbound interface ID
+ */
+ uint32_t if_id_in;
+
+ /**
+ * Outbound interface ID
+ */
+ uint32_t if_id_out;
+
/**
* inbound mark used for this child_sa
*/
.spi = this->my_spi,
.proto = proto_ike2ip(this->protocol),
.mark = mark_in_sa(this),
+ .if_id = this->if_id_in,
};
kernel_ipsec_query_sa_t query = {};
.spi = this->other_spi,
.proto = proto_ike2ip(this->protocol),
.mark = this->mark_out,
+ .if_id = this->if_id_out,
};
kernel_ipsec_query_sa_t query = {};
.src_ts = other_ts,
.dst_ts = my_ts,
.mark = this->mark_in,
+ .if_id = this->if_id_in,
};
kernel_ipsec_query_policy_t query = {};
.src_ts = my_ts,
.dst_ts = other_ts,
.mark = this->mark_out,
+ .if_id = this->if_id_out,
.interface = this->config->get_interface(this->config),
};
kernel_ipsec_query_policy_t query = {};
METHOD(child_sa_t, get_mark, mark_t,
private_child_sa_t *this, bool inbound)
{
- if (inbound)
- {
- return this->mark_in;
- }
- return this->mark_out;
+ return inbound ? this->mark_in : this->mark_out;
+}
+
+METHOD(child_sa_t, get_if_id, uint32_t,
+ private_child_sa_t *this, bool inbound)
+{
+ return inbound ? this->if_id_in : this->if_id_out;
}
METHOD(child_sa_t, get_lifetime, time_t,
if (!this->reqid_allocated && !this->static_reqid)
{
status = charon->kernel->alloc_reqid(charon->kernel, my_ts, other_ts,
- this->mark_in, this->mark_out, 0, 0,
- &this->reqid);
+ this->mark_in, this->mark_out, this->if_id_in,
+ this->if_id_out, &this->reqid);
if (status != SUCCESS)
{
my_ts->destroy(my_ts);
.spi = spi,
.proto = proto_ike2ip(this->protocol),
.mark = inbound ? mark_in_sa(this) : this->mark_out,
+ .if_id = inbound ? this->if_id_in : this->if_id_out,
};
sa = (kernel_ipsec_add_sa_t){
.reqid = this->reqid,
.src_ts = other_ts,
.dst_ts = my_ts,
.mark = this->mark_in,
+ .if_id = this->if_id_in,
};
kernel_ipsec_manage_policy_t in_policy = {
.type = type,
.src_ts = my_ts,
.dst_ts = other_ts,
.mark = this->mark_out,
+ .if_id = this->if_id_out,
.interface = this->config->get_interface(this->config),
};
kernel_ipsec_manage_policy_t out_policy = {
.src_ts = other_ts,
.dst_ts = my_ts,
.mark = this->mark_in,
+ .if_id = this->if_id_in,
};
kernel_ipsec_manage_policy_t in_policy = {
.type = type,
.src_ts = my_ts,
.dst_ts = other_ts,
.mark = this->mark_out,
+ .if_id = this->if_id_out,
.interface = this->config->get_interface(this->config),
};
kernel_ipsec_manage_policy_t out_policy = {
array_create_enumerator(this->other_ts));
status = charon->kernel->alloc_reqid(
charon->kernel, my_ts_list, other_ts_list,
- this->mark_in, this->mark_out, 0, 0, &this->reqid);
+ this->mark_in, this->mark_out, this->if_id_in,
+ this->if_id_out, &this->reqid);
my_ts_list->destroy(my_ts_list);
other_ts_list->destroy(other_ts_list);
if (status != SUCCESS)
.spi = this->other_spi,
.proto = proto_ike2ip(this->protocol),
.mark = this->mark_out,
+ .if_id = this->if_id_out,
};
kernel_ipsec_del_sa_t sa = {
.cpi = this->other_cpi,
.spi = this->my_spi,
.proto = proto_ike2ip(this->protocol),
.mark = mark_in_sa(this),
+ .if_id = this->if_id_in,
};
kernel_ipsec_update_sa_t sa = {
.cpi = this->ipcomp != IPCOMP_NONE ? this->my_cpi : 0,
.spi = this->other_spi,
.proto = proto_ike2ip(this->protocol),
.mark = this->mark_out,
+ .if_id = this->if_id_out,
};
kernel_ipsec_update_sa_t sa = {
.cpi = this->ipcomp != IPCOMP_NONE ? this->other_cpi : 0,
.spi = this->my_spi,
.proto = proto_ike2ip(this->protocol),
.mark = mark_in_sa(this),
+ .if_id = this->if_id_in,
};
kernel_ipsec_del_sa_t sa = {
.cpi = this->my_cpi,
.spi = this->other_spi,
.proto = proto_ike2ip(this->protocol),
.mark = this->mark_out,
+ .if_id = this->if_id_out,
};
kernel_ipsec_del_sa_t sa = {
.cpi = this->other_cpi,
{
if (charon->kernel->release_reqid(charon->kernel,
this->reqid, this->mark_in, this->mark_out,
- 0, 0) != SUCCESS)
+ this->if_id_in, this->if_id_out) != SUCCESS)
{
DBG1(DBG_CHD, "releasing reqid %u failed", this->reqid);
}
*/
child_sa_t * child_sa_create(host_t *me, host_t* other,
child_cfg_t *config, uint32_t reqid, bool encap,
- u_int mark_in, u_int mark_out)
+ uint32_t mark_in, uint32_t mark_out,
+ uint32_t if_id_in, uint32_t if_id_out)
{
private_child_sa_t *this;
- static refcount_t unique_id = 0, unique_mark = 0;
- refcount_t mark = 0;
+ static refcount_t unique_id = 0, unique_mark = 0, unique_if_id = 0;
INIT(this,
.public = {
.get_installtime = _get_installtime,
.get_usestats = _get_usestats,
.get_mark = _get_mark,
+ .get_if_id = _get_if_id,
.has_encap = _has_encap,
.get_ipcomp = _get_ipcomp,
.set_ipcomp = _set_ipcomp,
.unique_id = ref_get(&unique_id),
.mark_in = config->get_mark(config, TRUE),
.mark_out = config->get_mark(config, FALSE),
+ .if_id_in = config->get_if_id(config, TRUE),
+ .if_id_out = config->get_if_id(config, FALSE),
.install_time = time_monotonic(NULL),
.policies_fwd_out = config->has_option(config, OPT_FWD_OUT_POLICIES),
);
{
this->mark_out.value = mark_out;
}
+ if (if_id_in)
+ {
+ this->if_id_in = if_id_in;
+ }
+ if (if_id_out)
+ {
+ this->if_id_out = if_id_out;
+ }
if (MARK_IS_UNIQUE(this->mark_in.value) ||
MARK_IS_UNIQUE(this->mark_out.value))
{
- bool unique_dir;
-
- unique_dir = this->mark_in.value == MARK_UNIQUE_DIR ||
- this->mark_out.value == MARK_UNIQUE_DIR;
+ refcount_t mark = 0;
+ bool unique_dir = this->mark_in.value == MARK_UNIQUE_DIR ||
+ this->mark_out.value == MARK_UNIQUE_DIR;
if (!unique_dir)
{
}
if (MARK_IS_UNIQUE(this->mark_in.value))
{
- if (unique_dir)
- {
- mark = ref_get(&unique_mark);
- }
- this->mark_in.value = mark;
+ this->mark_in.value = unique_dir ? ref_get(&unique_mark) : mark;
}
if (MARK_IS_UNIQUE(this->mark_out.value))
{
- if (unique_dir)
- {
- mark = ref_get(&unique_mark);
- }
- this->mark_out.value = mark;
+ this->mark_out.value = unique_dir ? ref_get(&unique_mark) : mark;
+ }
+ }
+
+ if (IF_ID_IS_UNIQUE(this->if_id_in) ||
+ IF_ID_IS_UNIQUE(this->if_id_out))
+ {
+ refcount_t if_id = 0;
+ bool unique_dir = this->if_id_in == IF_ID_UNIQUE_DIR ||
+ this->if_id_out == IF_ID_UNIQUE_DIR;
+
+ if (!unique_dir)
+ {
+ if_id = ref_get(&unique_if_id);
+ }
+ if (IF_ID_IS_UNIQUE(this->if_id_in))
+ {
+ this->if_id_in = unique_dir ? ref_get(&unique_if_id) : if_id;
+ }
+ if (IF_ID_IS_UNIQUE(this->if_id_out))
+ {
+ this->if_id_out = unique_dir ? ref_get(&unique_if_id) : if_id;
}
}