proper update of IPsec SA when roaming a host-to-host tunnel

roaming of IPsec SAs using virtual IPs
This commit is contained in:
Martin Willi
2007-07-02 09:49:22 +00:00
parent 530dd57c6a
commit face844a87
5 changed files with 159 additions and 96 deletions
+14 -9
View File
@@ -231,6 +231,9 @@ struct addr_entry_t {
/** virtual IP managed by us */
bool virtual;
/** scope of the address */
u_char scope;
/** Number of times this IP is used, if virtual */
u_int refcount;
};
@@ -695,6 +698,7 @@ static void process_addr(private_kernel_interface_t *this,
addr->ip = host->clone(host);
addr->virtual = FALSE;
addr->refcount = 1;
addr->scope = msg->ifa_scope;
iface->addrs->insert_last(iface->addrs, addr);
if (event)
@@ -1078,6 +1082,10 @@ static hook_result_t addr_hook(private_kernel_interface_t *this,
{ /* skip virtual interfaces added by us */
return HOOK_SKIP;
}
if (in->scope >= RT_SCOPE_LINK)
{ /* skip addresses with a unusable scope */
return HOOK_SKIP;
}
*out = in->ip;
return HOOK_NEXT;
}
@@ -1497,6 +1505,7 @@ static status_t add_ip(private_kernel_interface_t *this,
addr->ip = virtual_ip->clone(virtual_ip);
addr->refcount = 1;
addr->virtual = TRUE;
addr->scope = RT_SCOPE_UNIVERSE;
pthread_mutex_lock(&this->mutex);
iface->addrs->insert_last(iface->addrs, addr);
pthread_mutex_unlock(&this->mutex);
@@ -2001,8 +2010,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 high_prio, mode_t mode,
bool update)
u_int32_t reqid, bool high_prio, mode_t mode)
{
iterator_t *iterator;
policy_entry_t *current, *policy;
@@ -2026,12 +2034,9 @@ static status_t add_policy(private_kernel_interface_t *this,
policy->direction == current->direction)
{
/* use existing policy */
if (!update)
{
current->refcount++;
DBG2(DBG_KNL, "policy %R===%R already exists, increasing ",
"refcount", src_ts, dst_ts);
}
current->refcount++;
DBG2(DBG_KNL, "policy %R===%R already exists, increasing ",
"refcount", src_ts, dst_ts);
free(policy);
policy = current;
found = TRUE;
@@ -2318,7 +2323,7 @@ kernel_interface_t *kernel_interface_create()
this->public.update_sa = (status_t(*)(kernel_interface_t*,u_int32_t,protocol_id_t,host_t*,host_t*,host_t*,host_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,mode_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,mode_t))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.get_interface = (char*(*)(kernel_interface_t*,host_t*))get_interface_name;