child-sa: Add support for per-CPU SAs
The CPU ID is also set on inbound SAs as it can be used to configure RSS or some eBPF program.
This commit is contained in:
@@ -820,6 +820,7 @@ static void process_child_add(private_ha_dispatcher_t *this,
|
|||||||
|
|
||||||
child_sa_create_t data = {
|
child_sa_create_t data = {
|
||||||
.encap = ike_sa->has_condition(ike_sa, COND_NAT_ANY),
|
.encap = ike_sa->has_condition(ike_sa, COND_NAT_ANY),
|
||||||
|
.cpu = CPU_ID_MAX,
|
||||||
};
|
};
|
||||||
child_sa = child_sa_create(ike_sa->get_my_host(ike_sa),
|
child_sa = child_sa_create(ike_sa->get_my_host(ike_sa),
|
||||||
ike_sa->get_other_host(ike_sa), config, &data);
|
ike_sa->get_other_host(ike_sa), config, &data);
|
||||||
|
|||||||
@@ -125,6 +125,7 @@ METHOD(listener_t, ike_updown, bool,
|
|||||||
child_sa_create_t child = {
|
child_sa_create_t child = {
|
||||||
.if_id_in_def = ike_sa->get_if_id(ike_sa, TRUE),
|
.if_id_in_def = ike_sa->get_if_id(ike_sa, TRUE),
|
||||||
.if_id_out_def = ike_sa->get_if_id(ike_sa, FALSE),
|
.if_id_out_def = ike_sa->get_if_id(ike_sa, FALSE),
|
||||||
|
.cpu = CPU_ID_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
INIT(entry,
|
INIT(entry,
|
||||||
|
|||||||
+63
-11
@@ -181,6 +181,16 @@ struct private_child_sa_t {
|
|||||||
*/
|
*/
|
||||||
uint32_t if_id_out;
|
uint32_t if_id_out;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CPU ID to use for the outbound SA
|
||||||
|
*/
|
||||||
|
uint32_t cpu;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to enable per-CPU feature for this SA
|
||||||
|
*/
|
||||||
|
bool per_cpu;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* inbound mark used for this child_sa
|
* inbound mark used for this child_sa
|
||||||
*/
|
*/
|
||||||
@@ -834,6 +844,28 @@ METHOD(child_sa_t, set_acquire_seq, void,
|
|||||||
this->seq = seq;
|
this->seq = seq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(child_sa_t, get_cpu, uint32_t,
|
||||||
|
private_child_sa_t *this)
|
||||||
|
{
|
||||||
|
return this->cpu;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(child_sa_t, use_per_cpu, bool,
|
||||||
|
private_child_sa_t *this)
|
||||||
|
{
|
||||||
|
return this->per_cpu;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(child_sa_t, set_per_cpu, void,
|
||||||
|
private_child_sa_t *this, bool per_cpu)
|
||||||
|
{
|
||||||
|
if (!per_cpu)
|
||||||
|
{
|
||||||
|
this->cpu = CPU_ID_MAX;
|
||||||
|
}
|
||||||
|
this->per_cpu = per_cpu;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(child_sa_t, get_lifetime, time_t,
|
METHOD(child_sa_t, get_lifetime, time_t,
|
||||||
private_child_sa_t *this, bool hard)
|
private_child_sa_t *this, bool hard)
|
||||||
{
|
{
|
||||||
@@ -1054,7 +1086,7 @@ static status_t install_internal(private_child_sa_t *this, chunk_t encr,
|
|||||||
.ipcomp = this->ipcomp,
|
.ipcomp = this->ipcomp,
|
||||||
.cpi = cpi,
|
.cpi = cpi,
|
||||||
.encap = this->encap,
|
.encap = this->encap,
|
||||||
.cpu = CPU_ID_MAX,
|
.cpu = this->per_cpu ? this->cpu : CPU_ID_MAX,
|
||||||
.hw_offload = this->config->get_hw_offload(this->config),
|
.hw_offload = this->config->get_hw_offload(this->config),
|
||||||
.mark = this->config->get_set_mark(this->config, inbound),
|
.mark = this->config->get_set_mark(this->config, inbound),
|
||||||
.esn = esn,
|
.esn = esn,
|
||||||
@@ -1101,12 +1133,25 @@ METHOD(child_sa_t, install, status_t,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check kernel interface if policy updates are required
|
* Check whether to install policies for this CHILD_SA
|
||||||
*/
|
*/
|
||||||
static bool require_policy_update()
|
static bool require_policies(private_child_sa_t *this)
|
||||||
|
{
|
||||||
|
return !this->config->has_option(this->config, OPT_NO_POLICIES);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if policy updates are required
|
||||||
|
*/
|
||||||
|
static bool require_policy_update(private_child_sa_t *this)
|
||||||
{
|
{
|
||||||
kernel_feature_t f;
|
kernel_feature_t f;
|
||||||
|
|
||||||
|
if (!require_policies(this))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
f = charon->kernel->get_features(charon->kernel);
|
f = charon->kernel->get_features(charon->kernel);
|
||||||
return !(f & KERNEL_NO_POLICY_UPDATES);
|
return !(f & KERNEL_NO_POLICY_UPDATES);
|
||||||
}
|
}
|
||||||
@@ -1217,6 +1262,7 @@ static status_t install_policies_outbound(private_child_sa_t *this,
|
|||||||
.hw_offload = this->config->get_hw_offload(this->config),
|
.hw_offload = this->config->get_hw_offload(this->config),
|
||||||
.src = my_addr,
|
.src = my_addr,
|
||||||
.dst = other_addr,
|
.dst = other_addr,
|
||||||
|
.pcpu_acquires = this->per_cpu,
|
||||||
.sa = other_sa,
|
.sa = other_sa,
|
||||||
};
|
};
|
||||||
uint32_t reqid = other_sa->reqid;
|
uint32_t reqid = other_sa->reqid;
|
||||||
@@ -1330,6 +1376,7 @@ static void del_policies_outbound(private_child_sa_t *this,
|
|||||||
.hw_offload = this->config->get_hw_offload(this->config),
|
.hw_offload = this->config->get_hw_offload(this->config),
|
||||||
.src = my_addr,
|
.src = my_addr,
|
||||||
.dst = other_addr,
|
.dst = other_addr,
|
||||||
|
.pcpu_acquires = this->per_cpu,
|
||||||
.sa = other_sa,
|
.sa = other_sa,
|
||||||
};
|
};
|
||||||
uint32_t reqid = other_sa->reqid;
|
uint32_t reqid = other_sa->reqid;
|
||||||
@@ -1427,7 +1474,7 @@ METHOD(child_sa_t, install_policies, status_t,
|
|||||||
this->outbound_state |= CHILD_OUTBOUND_POLICIES;
|
this->outbound_state |= CHILD_OUTBOUND_POLICIES;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this->config->has_option(this->config, OPT_NO_POLICIES))
|
if (require_policies(this))
|
||||||
{
|
{
|
||||||
policy_priority_t priority;
|
policy_priority_t priority;
|
||||||
ipsec_sa_cfg_t my_sa, other_sa;
|
ipsec_sa_cfg_t my_sa, other_sa;
|
||||||
@@ -1473,11 +1520,12 @@ METHOD(child_sa_t, install_policies, status_t,
|
|||||||
*
|
*
|
||||||
* However, if we use labels with SELinux, we can't as we don't set SPIs
|
* However, if we use labels with SELinux, we can't as we don't set SPIs
|
||||||
* on the policy in order to match SAs with other labels that match the generic
|
* on the policy in order to match SAs with other labels that match the generic
|
||||||
* label that's used on the policies.
|
* label that's used on the policies. The same is the case for per-CPU SAs.
|
||||||
*/
|
*/
|
||||||
static bool install_outbound_immediately(private_child_sa_t *this)
|
static bool install_outbound_immediately(private_child_sa_t *this)
|
||||||
{
|
{
|
||||||
if (charon->kernel->get_features(charon->kernel) & KERNEL_POLICY_SPI)
|
if (charon->kernel->get_features(charon->kernel) & KERNEL_POLICY_SPI &&
|
||||||
|
!this->per_cpu)
|
||||||
{
|
{
|
||||||
if (this->config->get_label_mode(this->config) == SEC_LABEL_MODE_SELINUX)
|
if (this->config->get_label_mode(this->config) == SEC_LABEL_MODE_SELINUX)
|
||||||
{
|
{
|
||||||
@@ -1538,7 +1586,7 @@ METHOD(child_sa_t, install_outbound, status_t,
|
|||||||
{
|
{
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
if (!this->config->has_option(this->config, OPT_NO_POLICIES) &&
|
if (require_policies(this) &&
|
||||||
!(this->outbound_state & CHILD_OUTBOUND_POLICIES))
|
!(this->outbound_state & CHILD_OUTBOUND_POLICIES))
|
||||||
{
|
{
|
||||||
ipsec_sa_cfg_t my_sa, other_sa;
|
ipsec_sa_cfg_t my_sa, other_sa;
|
||||||
@@ -1582,7 +1630,7 @@ METHOD(child_sa_t, remove_outbound, void,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this->config->has_option(this->config, OPT_NO_POLICIES) &&
|
if (require_policies(this) &&
|
||||||
(this->outbound_state & CHILD_OUTBOUND_POLICIES))
|
(this->outbound_state & CHILD_OUTBOUND_POLICIES))
|
||||||
{
|
{
|
||||||
ipsec_sa_cfg_t my_sa, other_sa;
|
ipsec_sa_cfg_t my_sa, other_sa;
|
||||||
@@ -1749,8 +1797,7 @@ METHOD(child_sa_t, update, status_t,
|
|||||||
this->config->has_option(this->config,
|
this->config->has_option(this->config,
|
||||||
OPT_PROXY_MODE);
|
OPT_PROXY_MODE);
|
||||||
|
|
||||||
if (!this->config->has_option(this->config, OPT_NO_POLICIES) &&
|
if (require_policy_update(this) && array_count(this->my_ts) &&
|
||||||
require_policy_update() && array_count(this->my_ts) &&
|
|
||||||
array_count(this->other_ts))
|
array_count(this->other_ts))
|
||||||
{
|
{
|
||||||
ipsec_sa_cfg_t my_sa, other_sa;
|
ipsec_sa_cfg_t my_sa, other_sa;
|
||||||
@@ -1949,7 +1996,7 @@ METHOD(child_sa_t, destroy, void,
|
|||||||
|
|
||||||
set_state(this, CHILD_DESTROYING);
|
set_state(this, CHILD_DESTROYING);
|
||||||
|
|
||||||
if (!this->config->has_option(this->config, OPT_NO_POLICIES))
|
if (require_policies(this))
|
||||||
{
|
{
|
||||||
ipsec_sa_cfg_t my_sa, other_sa;
|
ipsec_sa_cfg_t my_sa, other_sa;
|
||||||
uint32_t manual_prio;
|
uint32_t manual_prio;
|
||||||
@@ -2093,6 +2140,9 @@ child_sa_t *child_sa_create(host_t *me, host_t *other, child_cfg_t *config,
|
|||||||
.get_mark = _get_mark,
|
.get_mark = _get_mark,
|
||||||
.get_if_id = _get_if_id,
|
.get_if_id = _get_if_id,
|
||||||
.get_label = _get_label,
|
.get_label = _get_label,
|
||||||
|
.get_cpu = _get_cpu,
|
||||||
|
.set_per_cpu = _set_per_cpu,
|
||||||
|
.use_per_cpu = _use_per_cpu,
|
||||||
.get_acquire_seq = _get_acquire_seq,
|
.get_acquire_seq = _get_acquire_seq,
|
||||||
.set_acquire_seq = _set_acquire_seq,
|
.set_acquire_seq = _set_acquire_seq,
|
||||||
.has_encap = _has_encap,
|
.has_encap = _has_encap,
|
||||||
@@ -2133,6 +2183,8 @@ child_sa_t *child_sa_create(host_t *me, host_t *other, child_cfg_t *config,
|
|||||||
.if_id_in = config->get_if_id(config, TRUE) ?: data->if_id_in_def,
|
.if_id_in = config->get_if_id(config, TRUE) ?: data->if_id_in_def,
|
||||||
.if_id_out = config->get_if_id(config, FALSE) ?: data->if_id_out_def,
|
.if_id_out = config->get_if_id(config, FALSE) ?: data->if_id_out_def,
|
||||||
.label = data->label ? data->label->clone(data->label) : NULL,
|
.label = data->label ? data->label->clone(data->label) : NULL,
|
||||||
|
.cpu = data->cpu,
|
||||||
|
.per_cpu = data->per_cpu,
|
||||||
.seq = data->seq,
|
.seq = data->seq,
|
||||||
.install_time = time_monotonic(NULL),
|
.install_time = time_monotonic(NULL),
|
||||||
.policies_fwd_out = config->has_option(config, OPT_FWD_OUT_POLICIES),
|
.policies_fwd_out = config->has_option(config, OPT_FWD_OUT_POLICIES),
|
||||||
|
|||||||
@@ -390,6 +390,28 @@ struct child_sa_t {
|
|||||||
*/
|
*/
|
||||||
sec_label_t *(*get_label)(child_sa_t *this);
|
sec_label_t *(*get_label)(child_sa_t *this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the CPU ID used with this CHILD_SA.
|
||||||
|
*
|
||||||
|
* @return CPU used with this CHILD_SA
|
||||||
|
*/
|
||||||
|
uint32_t (*get_cpu)(child_sa_t *this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the per-CPU SA feature is enabled for this CHILD_SA.
|
||||||
|
*
|
||||||
|
* @return TRUE if per-CPU SA feature is enabled
|
||||||
|
*/
|
||||||
|
bool (*use_per_cpu)(child_sa_t *this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether the per-CPU SA feature is enabled for this CHILD_SA.
|
||||||
|
*
|
||||||
|
* @param per_cpu TRUE to enable per-CPU SA feature, FALSE also resets
|
||||||
|
* the CPU ID
|
||||||
|
*/
|
||||||
|
void (*set_per_cpu)(child_sa_t *this, bool per_cpu);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the optional sequence number associated with the acquire that
|
* Get the optional sequence number associated with the acquire that
|
||||||
* triggered this CHILD_SA.
|
* triggered this CHILD_SA.
|
||||||
@@ -575,6 +597,10 @@ struct child_sa_create_t {
|
|||||||
uint32_t if_id_out_def;
|
uint32_t if_id_out_def;
|
||||||
/** Optional security label to apply on SAs (cloned) */
|
/** Optional security label to apply on SAs (cloned) */
|
||||||
sec_label_t *label;
|
sec_label_t *label;
|
||||||
|
/** Optional CPU ID, CPU_ID_MAX if not specified */
|
||||||
|
uint32_t cpu;
|
||||||
|
/** Optional flag to enable per-CPU SA feature */
|
||||||
|
bool per_cpu;
|
||||||
/** Optional sequence number associated with the acquire that triggered
|
/** Optional sequence number associated with the acquire that triggered
|
||||||
* this SA */
|
* this SA */
|
||||||
uint32_t seq;
|
uint32_t seq;
|
||||||
|
|||||||
@@ -1567,6 +1567,7 @@ quick_mode_t *quick_mode_create(ike_sa_t *ike_sa, child_cfg_t *config,
|
|||||||
.abort = _abort_,
|
.abort = _abort_,
|
||||||
},
|
},
|
||||||
.child = {
|
.child = {
|
||||||
|
.cpu = CPU_ID_MAX,
|
||||||
.seq = seq,
|
.seq = seq,
|
||||||
},
|
},
|
||||||
.ike_sa = ike_sa,
|
.ike_sa = ike_sa,
|
||||||
|
|||||||
@@ -2833,6 +2833,7 @@ child_create_t *child_create_create(ike_sa_t *ike_sa,
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
.child = {
|
.child = {
|
||||||
|
.cpu = CPU_ID_MAX,
|
||||||
.seq = seq,
|
.seq = seq,
|
||||||
},
|
},
|
||||||
.ike_sa = ike_sa,
|
.ike_sa = ike_sa,
|
||||||
|
|||||||
@@ -349,6 +349,7 @@ METHOD(trap_manager_t, install, bool,
|
|||||||
* pass them in a later initiate() call */
|
* pass them in a later initiate() call */
|
||||||
.if_id_in_def = peer->get_if_id(peer, TRUE),
|
.if_id_in_def = peer->get_if_id(peer, TRUE),
|
||||||
.if_id_out_def = peer->get_if_id(peer, FALSE),
|
.if_id_out_def = peer->get_if_id(peer, FALSE),
|
||||||
|
.cpu = CPU_ID_MAX,
|
||||||
};
|
};
|
||||||
child_sa = child_sa_create(me, other, child, &child_data);
|
child_sa = child_sa_create(me, other, child, &child_data);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user