add priority management for kernel policy

let ROUTED policies installed, until manuall removed
introduced new naming scheme to allow proper shutdown of IKE/CHILD_SAs
ike_sa_manager cleanups
This commit is contained in:
Martin Willi
2006-09-08 13:10:52 +00:00
parent 1239c6f40b
commit a095243f60
12 changed files with 256 additions and 221 deletions
+17 -4
View File
@@ -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;
+2 -1
View File
@@ -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.
+1 -49
View File
@@ -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);
}
/**