diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/charon/kernel/kernel_interface.c | 12 | ||||
-rw-r--r-- | src/charon/sa/child_sa.c | 11 | ||||
-rw-r--r-- | src/charon/sa/child_sa.h | 4 | ||||
-rw-r--r-- | src/charon/sa/ike_sa.c | 2 | ||||
-rw-r--r-- | src/charon/sa/tasks/child_create.c | 19 |
5 files changed, 28 insertions, 20 deletions
diff --git a/src/charon/kernel/kernel_interface.c b/src/charon/kernel/kernel_interface.c index 81d1e8b2e..8e16ba1b3 100644 --- a/src/charon/kernel/kernel_interface.c +++ b/src/charon/kernel/kernel_interface.c @@ -5,9 +5,6 @@ * Copyright (C) 2006 Daniel Roethlisberger * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil - * Copyright (C) 2003 Herbert Xu. - * - * Based on xfrm code from pluto. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -227,6 +224,9 @@ struct policy_entry_t { /** direction of this policy: in, out, forward */ u_int8_t direction; + /** protocol ID: ESP/AH */ + protocol_id_t proto; + /** reqid of the policy */ u_int32_t reqid; @@ -2612,14 +2612,16 @@ static status_t add_policy(private_kernel_interface_t *this, memset(policy, 0, sizeof(policy_entry_t)); policy->sel = ts2selector(src_ts, dst_ts); policy->direction = direction; + policy->proto = protocol; /* find the policy, which matches EXACTLY */ pthread_mutex_lock(&this->mutex); iterator = this->policies->create_iterator(this->policies, TRUE); while (iterator->iterate(iterator, (void**)¤t)) { - if (memcmp(¤t->sel, &policy->sel, sizeof(struct xfrm_selector)) == 0 && - policy->direction == current->direction) + if (memeq(¤t->sel, &policy->sel, sizeof(struct xfrm_selector)) && + policy->direction == current->direction && + policy->proto == current->proto) { /* use existing policy */ current->refcount++; 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); |