child-sa: Use flags to track installation of outbound SA and policies separately
This commit is contained in:
+28
-23
@@ -40,10 +40,10 @@ ENUM(child_sa_state_names, CHILD_CREATED, CHILD_DESTROYING,
|
|||||||
"DESTROYING",
|
"DESTROYING",
|
||||||
);
|
);
|
||||||
|
|
||||||
ENUM(child_sa_outbound_state_names, CHILD_OUTBOUND_NONE, CHILD_OUTBOUND_INSTALLED,
|
ENUM_FLAGS(child_sa_outbound_state_names, CHILD_OUTBOUND_REGISTERED, CHILD_OUTBOUND_POLICIES,
|
||||||
"NONE",
|
|
||||||
"REGISTERED",
|
"REGISTERED",
|
||||||
"INSTALLED",
|
"SA",
|
||||||
|
"POLICIES",
|
||||||
);
|
);
|
||||||
|
|
||||||
typedef struct private_child_sa_t private_child_sa_t;
|
typedef struct private_child_sa_t private_child_sa_t;
|
||||||
@@ -547,7 +547,7 @@ static status_t update_usebytes(private_child_sa_t *this, bool inbound)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (this->other_spi && this->outbound_state == CHILD_OUTBOUND_INSTALLED)
|
if (this->other_spi && (this->outbound_state & CHILD_OUTBOUND_SA))
|
||||||
{
|
{
|
||||||
kernel_ipsec_sa_id_t id = {
|
kernel_ipsec_sa_id_t id = {
|
||||||
.src = this->my_addr,
|
.src = this->my_addr,
|
||||||
@@ -788,7 +788,7 @@ static status_t install_internal(private_child_sa_t *this, chunk_t encr,
|
|||||||
{
|
{
|
||||||
tfc = this->config->get_tfc(this->config);
|
tfc = this->config->get_tfc(this->config);
|
||||||
}
|
}
|
||||||
this->outbound_state = CHILD_OUTBOUND_INSTALLED;
|
this->outbound_state |= CHILD_OUTBOUND_SA;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG2(DBG_CHD, "adding %s %N SA", inbound ? "inbound" : "outbound",
|
DBG2(DBG_CHD, "adding %s %N SA", inbound ? "inbound" : "outbound",
|
||||||
@@ -1188,6 +1188,7 @@ METHOD(child_sa_t, install_policies, status_t,
|
|||||||
linked_list_t *my_ts_list, *other_ts_list;
|
linked_list_t *my_ts_list, *other_ts_list;
|
||||||
traffic_selector_t *my_ts, *other_ts;
|
traffic_selector_t *my_ts, *other_ts;
|
||||||
status_t status = SUCCESS;
|
status_t status = SUCCESS;
|
||||||
|
bool install_outbound = FALSE;
|
||||||
|
|
||||||
if (!this->reqid_allocated && !this->static_reqid)
|
if (!this->reqid_allocated && !this->static_reqid)
|
||||||
{
|
{
|
||||||
@@ -1207,12 +1208,17 @@ METHOD(child_sa_t, install_policies, status_t,
|
|||||||
this->reqid_allocated = TRUE;
|
this->reqid_allocated = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(this->outbound_state & CHILD_OUTBOUND_REGISTERED))
|
||||||
|
{
|
||||||
|
install_outbound = TRUE;
|
||||||
|
this->outbound_state |= CHILD_OUTBOUND_POLICIES;
|
||||||
|
}
|
||||||
|
|
||||||
if (!this->config->has_option(this->config, OPT_NO_POLICIES))
|
if (!this->config->has_option(this->config, OPT_NO_POLICIES))
|
||||||
{
|
{
|
||||||
policy_priority_t priority;
|
policy_priority_t priority;
|
||||||
ipsec_sa_cfg_t my_sa, other_sa;
|
ipsec_sa_cfg_t my_sa, other_sa;
|
||||||
uint32_t manual_prio;
|
uint32_t manual_prio;
|
||||||
bool install_outbound;
|
|
||||||
|
|
||||||
prepare_sa_cfg(this, &my_sa, &other_sa);
|
prepare_sa_cfg(this, &my_sa, &other_sa);
|
||||||
manual_prio = this->config->get_manual_prio(this->config);
|
manual_prio = this->config->get_manual_prio(this->config);
|
||||||
@@ -1222,7 +1228,6 @@ METHOD(child_sa_t, install_policies, status_t,
|
|||||||
this->trap = this->state == CHILD_CREATED;
|
this->trap = this->state == CHILD_CREATED;
|
||||||
priority = this->trap ? POLICY_PRIORITY_ROUTED
|
priority = this->trap ? POLICY_PRIORITY_ROUTED
|
||||||
: POLICY_PRIORITY_DEFAULT;
|
: POLICY_PRIORITY_DEFAULT;
|
||||||
install_outbound = this->outbound_state != CHILD_OUTBOUND_REGISTERED;
|
|
||||||
|
|
||||||
/* enumerate pairs of traffic selectors */
|
/* enumerate pairs of traffic selectors */
|
||||||
enumerator = create_policy_enumerator(this);
|
enumerator = create_policy_enumerator(this);
|
||||||
@@ -1250,7 +1255,6 @@ METHOD(child_sa_t, install_policies, status_t,
|
|||||||
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,
|
||||||
priority, manual_prio);
|
priority, manual_prio);
|
||||||
|
|
||||||
}
|
}
|
||||||
if (status != SUCCESS)
|
if (status != SUCCESS)
|
||||||
{
|
{
|
||||||
@@ -1281,7 +1285,7 @@ METHOD(child_sa_t, register_outbound, void,
|
|||||||
this->encr_r = chunk_clone(encr);
|
this->encr_r = chunk_clone(encr);
|
||||||
this->integ_r = chunk_clone(integ);
|
this->integ_r = chunk_clone(integ);
|
||||||
this->tfcv3 = tfcv3;
|
this->tfcv3 = tfcv3;
|
||||||
this->outbound_state = CHILD_OUTBOUND_REGISTERED;
|
this->outbound_state |= CHILD_OUTBOUND_REGISTERED;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(child_sa_t, install_outbound, status_t,
|
METHOD(child_sa_t, install_outbound, status_t,
|
||||||
@@ -1289,17 +1293,19 @@ METHOD(child_sa_t, install_outbound, status_t,
|
|||||||
{
|
{
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
traffic_selector_t *my_ts, *other_ts;
|
traffic_selector_t *my_ts, *other_ts;
|
||||||
status_t status;
|
status_t status = SUCCESS;
|
||||||
|
|
||||||
status = install_internal(this, this->encr_r, this->integ_r,
|
status = install_internal(this, this->encr_r, this->integ_r,
|
||||||
this->other_spi, this->other_cpi, FALSE, FALSE,
|
this->other_spi, this->other_cpi, FALSE,
|
||||||
this->tfcv3);
|
FALSE, this->tfcv3);
|
||||||
chunk_clear(&this->encr_r);
|
chunk_clear(&this->encr_r);
|
||||||
chunk_clear(&this->integ_r);
|
chunk_clear(&this->integ_r);
|
||||||
|
this->outbound_state &= ~CHILD_OUTBOUND_REGISTERED;
|
||||||
if (status != SUCCESS)
|
if (status != SUCCESS)
|
||||||
{
|
{
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
this->outbound_state |= CHILD_OUTBOUND_POLICIES;
|
||||||
if (!this->config->has_option(this->config, OPT_NO_POLICIES))
|
if (!this->config->has_option(this->config, OPT_NO_POLICIES))
|
||||||
{
|
{
|
||||||
ipsec_sa_cfg_t my_sa, other_sa;
|
ipsec_sa_cfg_t my_sa, other_sa;
|
||||||
@@ -1340,20 +1346,19 @@ METHOD(child_sa_t, remove_outbound, void,
|
|||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
traffic_selector_t *my_ts, *other_ts;
|
traffic_selector_t *my_ts, *other_ts;
|
||||||
|
|
||||||
switch (this->outbound_state)
|
if (!(this->outbound_state & CHILD_OUTBOUND_SA))
|
||||||
{
|
{
|
||||||
case CHILD_OUTBOUND_INSTALLED:
|
if (this->outbound_state & CHILD_OUTBOUND_REGISTERED)
|
||||||
break;
|
{
|
||||||
case CHILD_OUTBOUND_REGISTERED:
|
|
||||||
chunk_clear(&this->encr_r);
|
chunk_clear(&this->encr_r);
|
||||||
chunk_clear(&this->integ_r);
|
chunk_clear(&this->integ_r);
|
||||||
this->outbound_state = CHILD_OUTBOUND_NONE;
|
this->outbound_state = CHILD_OUTBOUND_NONE;
|
||||||
/* fall-through */
|
}
|
||||||
case CHILD_OUTBOUND_NONE:
|
return;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this->config->has_option(this->config, OPT_NO_POLICIES))
|
if (!this->config->has_option(this->config, OPT_NO_POLICIES) &&
|
||||||
|
(this->outbound_state & CHILD_OUTBOUND_POLICIES))
|
||||||
{
|
{
|
||||||
ipsec_sa_cfg_t my_sa, other_sa;
|
ipsec_sa_cfg_t my_sa, other_sa;
|
||||||
uint32_t manual_prio;
|
uint32_t manual_prio;
|
||||||
@@ -1598,8 +1603,8 @@ METHOD(child_sa_t, destroy, void,
|
|||||||
|
|
||||||
prepare_sa_cfg(this, &my_sa, &other_sa);
|
prepare_sa_cfg(this, &my_sa, &other_sa);
|
||||||
manual_prio = this->config->get_manual_prio(this->config);
|
manual_prio = this->config->get_manual_prio(this->config);
|
||||||
del_outbound = this->trap ||
|
del_outbound = (this->outbound_state & CHILD_OUTBOUND_POLICIES) ||
|
||||||
this->outbound_state == CHILD_OUTBOUND_INSTALLED;
|
this->trap;
|
||||||
|
|
||||||
/* delete all policies in the kernel */
|
/* delete all policies in the kernel */
|
||||||
enumerator = create_policy_enumerator(this);
|
enumerator = create_policy_enumerator(this);
|
||||||
@@ -1640,7 +1645,7 @@ METHOD(child_sa_t, destroy, void,
|
|||||||
};
|
};
|
||||||
charon->kernel->del_sa(charon->kernel, &id, &sa);
|
charon->kernel->del_sa(charon->kernel, &id, &sa);
|
||||||
}
|
}
|
||||||
if (this->other_spi && this->outbound_state == CHILD_OUTBOUND_INSTALLED)
|
if (this->other_spi && (this->outbound_state & CHILD_OUTBOUND_SA))
|
||||||
{
|
{
|
||||||
kernel_ipsec_sa_id_t id = {
|
kernel_ipsec_sa_id_t id = {
|
||||||
.src = this->my_addr,
|
.src = this->my_addr,
|
||||||
|
|||||||
@@ -102,17 +102,28 @@ enum child_sa_outbound_state_t {
|
|||||||
/**
|
/**
|
||||||
* Outbound SA is not installed
|
* Outbound SA is not installed
|
||||||
*/
|
*/
|
||||||
CHILD_OUTBOUND_NONE,
|
CHILD_OUTBOUND_NONE = 0,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data for the outbound SA has been registered, but not installed yet
|
* Data for the outbound SA has been registered during a rekeying (not set
|
||||||
|
* once the SA and policies are both installed)
|
||||||
*/
|
*/
|
||||||
CHILD_OUTBOUND_REGISTERED,
|
CHILD_OUTBOUND_REGISTERED = (1<<0),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The outbound SA is currently installed
|
* The outbound SA has been installed
|
||||||
*/
|
*/
|
||||||
CHILD_OUTBOUND_INSTALLED,
|
CHILD_OUTBOUND_SA = (1<<1),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The outbound policies have been installed
|
||||||
|
*/
|
||||||
|
CHILD_OUTBOUND_POLICIES = (1<<2),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The outbound SA and policies are both installed
|
||||||
|
*/
|
||||||
|
CHILD_OUTBOUND_INSTALLED = (CHILD_OUTBOUND_SA|CHILD_OUTBOUND_POLICIES),
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -121,7 +121,8 @@
|
|||||||
test_assert_msg(_state == _child->get_state(_child), "%N != %N", \
|
test_assert_msg(_state == _child->get_state(_child), "%N != %N", \
|
||||||
child_sa_state_names, _state, \
|
child_sa_state_names, _state, \
|
||||||
child_sa_state_names, _child->get_state(_child)); \
|
child_sa_state_names, _child->get_state(_child)); \
|
||||||
test_assert_msg(_outbound == _child->get_outbound_state(_child), "%N != %N", \
|
typeof(outbound) _cur_out = _child->get_outbound_state(_child); \
|
||||||
|
test_assert_msg(_outbound == _cur_out || _outbound & _cur_out, "%N != %N", \
|
||||||
child_sa_outbound_state_names, _outbound, \
|
child_sa_outbound_state_names, _outbound, \
|
||||||
child_sa_outbound_state_names, _child->get_outbound_state(_child)); \
|
child_sa_outbound_state_names, _child->get_outbound_state(_child)); \
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user