diff options
Diffstat (limited to 'src/charon/threads')
-rw-r--r-- | src/charon/threads/kernel_interface.c | 21 | ||||
-rw-r--r-- | src/charon/threads/kernel_interface.h | 3 | ||||
-rwxr-xr-x | src/charon/threads/stroke_interface.c | 50 |
3 files changed, 20 insertions, 54 deletions
diff --git a/src/charon/threads/kernel_interface.c b/src/charon/threads/kernel_interface.c index 796cd04a8..c74cf8f27 100644 --- a/src/charon/threads/kernel_interface.c +++ b/src/charon/threads/kernel_interface.c @@ -50,7 +50,8 @@ #define KERNEL_AH 51 /** default priority of installed policies */ -#define SPD_PRIORITY 1024 +#define PRIO_LOW 3000 +#define PRIO_HIGH 2000 #define BUFFER_SIZE 1024 @@ -979,7 +980,7 @@ static status_t add_policy(private_kernel_interface_t *this, traffic_selector_t *src_ts, traffic_selector_t *dst_ts, policy_dir_t direction, protocol_id_t protocol, - u_int32_t reqid, bool update) + u_int32_t reqid, bool high_prio, bool update) { iterator_t *iterator; kernel_policy_t *current, *policy; @@ -1011,6 +1012,14 @@ static status_t add_policy(private_kernel_interface_t *this, current->refcount++; this->logger->log(this->logger, CONTROL|LEVEL1, "policy already exists, increasing refcount"); + if (!high_prio) + { + /* if added policy is for a ROUTED child_sa, do not + * overwrite existing INSTALLED policy */ + iterator->destroy(iterator); + pthread_mutex_unlock(&this->pol_mutex); + return SUCCESS; + } } policy = current; found = TRUE; @@ -1035,7 +1044,11 @@ static status_t add_policy(private_kernel_interface_t *this, policy_info = (struct xfrm_userpolicy_info*)NLMSG_DATA(hdr); policy_info->sel = policy->sel; policy_info->dir = policy->direction; - policy_info->priority = SPD_PRIORITY; + /* calculate priority based on source selector size, small size = high prio */ + policy_info->priority = high_prio ? PRIO_HIGH : PRIO_LOW; + policy_info->priority -= policy->sel.prefixlen_s * 10; + policy_info->priority -= policy->sel.proto ? 2 : 0; + policy_info->priority -= policy->sel.sport_mask ? 1 : 0; policy_info->action = XFRM_POLICY_ALLOW; policy_info->share = XFRM_SHARE_ANY; pthread_mutex_unlock(&this->pol_mutex); @@ -1272,7 +1285,7 @@ kernel_interface_t *kernel_interface_create() this->public.update_sa = (status_t(*)(kernel_interface_t*,host_t*,u_int32_t,protocol_id_t,host_t*,host_t*,host_diff_t,host_diff_t))update_sa; this->public.query_sa = (status_t(*)(kernel_interface_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t*))query_sa; this->public.del_sa = (status_t(*)(kernel_interface_t*,host_t*,u_int32_t,protocol_id_t))del_sa; - this->public.add_policy = (status_t(*)(kernel_interface_t*,host_t*,host_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,protocol_id_t,u_int32_t,bool))add_policy; + this->public.add_policy = (status_t(*)(kernel_interface_t*,host_t*,host_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,protocol_id_t,u_int32_t,bool,bool))add_policy; this->public.query_policy = (status_t(*)(kernel_interface_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t*))query_policy; this->public.del_policy = (status_t(*)(kernel_interface_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t))del_policy; this->public.destroy = (void(*)(kernel_interface_t*)) destroy; diff --git a/src/charon/threads/kernel_interface.h b/src/charon/threads/kernel_interface.h index bafb1a6d1..4370e8253 100644 --- a/src/charon/threads/kernel_interface.h +++ b/src/charon/threads/kernel_interface.h @@ -207,6 +207,7 @@ struct kernel_interface_t { * @param direction direction of traffic, POLICY_IN, POLICY_OUT, POLICY_FWD * @param protocol protocol to use to protect traffic (AH/ESP) * @param reqid uniqe ID of an SA to use to enforce policy + * @param high_prio if TRUE, uses a higher priority than any with FALSE * @param update update an existing policy, if TRUE * @return * - SUCCESS @@ -217,7 +218,7 @@ struct kernel_interface_t { traffic_selector_t *src_ts, traffic_selector_t *dst_ts, policy_dir_t direction, protocol_id_t protocol, - u_int32_t reqid, bool update); + u_int32_t reqid, bool high_prio, bool update); /** * @brief Query the use time of a policy. diff --git a/src/charon/threads/stroke_interface.c b/src/charon/threads/stroke_interface.c index b8bdd5a99..3a39990a9 100755 --- a/src/charon/threads/stroke_interface.c +++ b/src/charon/threads/stroke_interface.c @@ -601,58 +601,10 @@ static void stroke_route(private_stroke_t *this, stroke_msg_t *msg, bool route) */ static void stroke_terminate(private_stroke_t *this, stroke_msg_t *msg) { - linked_list_t *ike_sas; - iterator_t *iterator; - int instances = 0; - connection_t *conn; - pop_string(msg, &(msg->terminate.name)); this->logger->log(this->logger, CONTROL, "received stroke: terminate \"%s\"", msg->terminate.name); - /* we have to do tricky tricks to give the most comprehensive output to the user. - * There are different cases: - * 1. Connection is available, but IKEv1: - * => just ignore it, let pluto print it - * 2. Connection is not available, but instances of a deleted connection template: - * => terminate them, and print their termination - * 3. Connection is not available, and and no instances are there: - * => show error about bad connection name - * 4. An IKEv2 connection is available, and may contain instances: - * => terminate and print, simple - */ - conn = charon->connections->get_connection_by_name(charon->connections, msg->terminate.name); - if (conn == NULL || conn->is_ikev2(conn)) - { - ike_sas = charon->ike_sa_manager->get_ike_sa_list_by_name(charon->ike_sa_manager, msg->terminate.name); - - iterator = ike_sas->create_iterator(ike_sas, TRUE); - while (iterator->has_next(iterator)) - { - ike_sa_id_t *ike_sa_id; - iterator->current(iterator, (void**)&ike_sa_id); - charon->ike_sa_manager->delete(charon->ike_sa_manager, ike_sa_id); - ike_sa_id->destroy(ike_sa_id); - instances++; - } - iterator->destroy(iterator); - ike_sas->destroy(ike_sas); - if (conn == NULL && instances == 0) - { - this->stroke_logger->log(this->stroke_logger, CONTROL, - "no connection named \"%s\"", - msg->terminate.name); - } - else - { - this->stroke_logger->log(this->stroke_logger, CONTROL, - "terminated %d instances of \"%s\"", - instances, msg->terminate.name); - } - } - if (conn) - { - conn->destroy(conn); - } + charon->ike_sa_manager->delete_by_name(charon->ike_sa_manager, msg->terminate.name); } /** |