aboutsummaryrefslogtreecommitdiffstats
path: root/src/charon/sa
diff options
context:
space:
mode:
Diffstat (limited to 'src/charon/sa')
-rw-r--r--src/charon/sa/child_sa.c11
-rw-r--r--src/charon/sa/child_sa.h4
-rw-r--r--src/charon/sa/ike_sa.c2
-rw-r--r--src/charon/sa/tasks/child_create.c19
4 files changed, 21 insertions, 15 deletions
diff --git a/src/charon/sa/child_sa.c b/src/charon/sa/child_sa.c
index 21f29a35e..443f9d9cd 100644
--- a/src/charon/sa/child_sa.c
+++ b/src/charon/sa/child_sa.c
@@ -662,14 +662,19 @@ static status_t update(private_child_sa_t *this, proposal_t *proposal,
}
static status_t add_policies(private_child_sa_t *this,
- linked_list_t *my_ts_list,
- linked_list_t *other_ts_list, mode_t mode)
+ linked_list_t *my_ts_list, linked_list_t *other_ts_list,
+ mode_t mode, protocol_id_t proto)
{
iterator_t *my_iter, *other_iter;
traffic_selector_t *my_ts, *other_ts;
/* use low prio for ROUTED policies */
bool high_prio = (this->state != CHILD_CREATED);
+ if (this->protocol == PROTO_NONE)
+ { /* update if not set yet */
+ this->protocol = proto;
+ }
+
/* iterate over both lists */
my_iter = my_ts_list->create_iterator(my_ts_list, TRUE);
other_iter = other_ts_list->create_iterator(other_ts_list, TRUE);
@@ -1029,7 +1034,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
this->public.add = (status_t(*)(child_sa_t*,proposal_t*,mode_t,prf_plus_t*))add;
this->public.update = (status_t(*)(child_sa_t*,proposal_t*,mode_t,prf_plus_t*))update;
this->public.update_hosts = (status_t (*)(child_sa_t*,host_t*,host_t*,bool))update_hosts;
- this->public.add_policies = (status_t (*)(child_sa_t*, linked_list_t*,linked_list_t*,mode_t))add_policies;
+ this->public.add_policies = (status_t (*)(child_sa_t*, linked_list_t*,linked_list_t*,mode_t,protocol_id_t))add_policies;
this->public.get_traffic_selectors = (linked_list_t*(*)(child_sa_t*,bool))get_traffic_selectors;
this->public.get_use_time = (status_t (*)(child_sa_t*,bool,time_t*))get_use_time;
this->public.set_state = (void(*)(child_sa_t*,child_sa_state_t))set_state;
diff --git a/src/charon/sa/child_sa.h b/src/charon/sa/child_sa.h
index 018f9225c..c566e563c 100644
--- a/src/charon/sa/child_sa.h
+++ b/src/charon/sa/child_sa.h
@@ -203,10 +203,12 @@ struct child_sa_t {
* @param my_ts traffic selectors for local site
* @param other_ts traffic selectors for remote site
* @param mode mode for the SA: tunnel/transport
+ * @param proto protocol for policy, ESP/AH
* @return SUCCESS or FAILED
*/
status_t (*add_policies)(child_sa_t *this, linked_list_t *my_ts_list,
- linked_list_t *other_ts_list, mode_t mode);
+ linked_list_t *other_ts_list, mode_t mode,
+ protocol_id_t proto);
/**
* Get the traffic selectors of added policies of local host.
diff --git a/src/charon/sa/ike_sa.c b/src/charon/sa/ike_sa.c
index feb8d8dad..41e4316b7 100644
--- a/src/charon/sa/ike_sa.c
+++ b/src/charon/sa/ike_sa.c
@@ -1263,7 +1263,7 @@ static status_t route(private_ike_sa_t *this, child_cfg_t *child_cfg)
my_ts = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, me);
other_ts = child_cfg->get_traffic_selectors(child_cfg, FALSE, NULL, other);
status = child_sa->add_policies(child_sa, my_ts, other_ts,
- child_cfg->get_mode(child_cfg));
+ child_cfg->get_mode(child_cfg), PROTO_NONE);
my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy));
other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy));
if (status == SUCCESS)
diff --git a/src/charon/sa/tasks/child_create.c b/src/charon/sa/tasks/child_create.c
index c011a2b0b..9d3243360 100644
--- a/src/charon/sa/tasks/child_create.c
+++ b/src/charon/sa/tasks/child_create.c
@@ -341,7 +341,6 @@ static status_t select_and_install(private_child_create_t *this, bool no_dh)
{
seed = chunk_cata("cc", nonce_i, nonce_r);
}
- prf_plus = prf_plus_create(this->ike_sa->get_child_prf(this->ike_sa), seed);
if (this->ipcomp != IPCOMP_NONE)
{
@@ -349,6 +348,15 @@ static status_t select_and_install(private_child_create_t *this, bool no_dh)
this->other_cpi);
}
+ status = this->child_sa->add_policies(this->child_sa, my_ts, other_ts,
+ this->mode, this->proposal->get_protocol(this->proposal));
+ if (status != SUCCESS)
+ {
+ SIG(CHILD_UP_FAILED, "unable to install IPsec policies (SPD) in kernel");
+ return NOT_FOUND;
+ }
+
+ prf_plus = prf_plus_create(this->ike_sa->get_child_prf(this->ike_sa), seed);
if (this->initiator)
{
status = this->child_sa->update(this->child_sa, this->proposal,
@@ -366,15 +374,6 @@ static status_t select_and_install(private_child_create_t *this, bool no_dh)
SIG(CHILD_UP_FAILED, "unable to install IPsec SA (SAD) in kernel");
return FAILED;
}
-
- status = this->child_sa->add_policies(this->child_sa, my_ts, other_ts,
- this->mode);
-
- if (status != SUCCESS)
- {
- SIG(CHILD_UP_FAILED, "unable to install IPsec policies (SPD) in kernel");
- return NOT_FOUND;
- }
/* add to IKE_SA, and remove from task */
this->child_sa->set_state(this->child_sa, CHILD_INSTALLED);
this->ike_sa->add_child_sa(this->ike_sa, this->child_sa);