mobike: try to keep existing source address before switching to another

This commit is contained in:
Martin Willi
2008-10-08 08:23:46 +00:00
parent e39b271b17
commit ce5b17082d
7 changed files with 43 additions and 29 deletions
+4 -3
View File
@@ -160,9 +160,10 @@ static status_t del_policy(private_kernel_interface_t *this,
/** /**
* Implementation of kernel_interface_t.get_source_addr * Implementation of kernel_interface_t.get_source_addr
*/ */
static host_t *get_source_addr(private_kernel_interface_t *this, host_t *dest) static host_t *get_source_addr(private_kernel_interface_t *this,
host_t *dest, host_t *src)
{ {
return this->net->get_source_addr(this->net, dest); return this->net->get_source_addr(this->net, dest, src);
} }
/** /**
@@ -329,7 +330,7 @@ kernel_interface_t *kernel_interface_create()
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.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.del_policy = (status_t(*)(kernel_interface_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t))del_policy;
this->public.get_source_addr = (host_t*(*)(kernel_interface_t*, host_t *dest))get_source_addr; this->public.get_source_addr = (host_t*(*)(kernel_interface_t*, host_t *dest, host_t *src))get_source_addr;
this->public.get_nexthop = (host_t*(*)(kernel_interface_t*, host_t *dest))get_nexthop; this->public.get_nexthop = (host_t*(*)(kernel_interface_t*, host_t *dest))get_nexthop;
this->public.get_interface = (char*(*)(kernel_interface_t*,host_t*))get_interface; this->public.get_interface = (char*(*)(kernel_interface_t*,host_t*))get_interface;
this->public.create_address_enumerator = (enumerator_t*(*)(kernel_interface_t*,bool,bool))create_address_enumerator; this->public.create_address_enumerator = (enumerator_t*(*)(kernel_interface_t*,bool,bool))create_address_enumerator;
+5 -1
View File
@@ -235,11 +235,15 @@ struct kernel_interface_t {
* *
* Does a route lookup to get the source address used to reach dest. * Does a route lookup to get the source address used to reach dest.
* The returned host is allocated and must be destroyed. * The returned host is allocated and must be destroyed.
* An optional src address can be used to check if a route is available
* for given source to dest.
* *
* @param dest target destination address * @param dest target destination address
* @param src source address to check, or NULL
* @return outgoing source address, NULL if unreachable * @return outgoing source address, NULL if unreachable
*/ */
host_t* (*get_source_addr)(kernel_interface_t *this, host_t *dest); host_t* (*get_source_addr)(kernel_interface_t *this,
host_t *dest, host_t *src);
/** /**
* Get the next hop for a destination. * Get the next hop for a destination.
+4 -1
View File
@@ -42,11 +42,14 @@ struct kernel_net_t {
* *
* Does a route lookup to get the source address used to reach dest. * Does a route lookup to get the source address used to reach dest.
* The returned host is allocated and must be destroyed. * The returned host is allocated and must be destroyed.
* An optional src address can be used to check if a route is available
* for given source to dest.
* *
* @param dest target destination address * @param dest target destination address
* @param src source address to check, or NULL
* @return outgoing source address, NULL if unreachable * @return outgoing source address, NULL if unreachable
*/ */
host_t* (*get_source_addr)(kernel_net_t *this, host_t *dest); host_t* (*get_source_addr)(kernel_net_t *this, host_t *dest, host_t *src);
/** /**
* Get the next hop for a destination. * Get the next hop for a destination.
@@ -1,5 +1,6 @@
/* /*
* Copyright (C) 2008 Tobias Brunner * Copyright (C) 2008 Tobias Brunner
* Copyright (C) 2005-2008 Martin Willi
* Hochschule fuer Technik Rapperswil * Hochschule fuer Technik Rapperswil
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
@@ -720,7 +721,7 @@ static bool addr_in_subnet(chunk_t addr, chunk_t net, int net_len)
* Get a route: If "nexthop", the nexthop is returned. source addr otherwise. * Get a route: If "nexthop", the nexthop is returned. source addr otherwise.
*/ */
static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest, static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest,
bool nexthop) bool nexthop, host_t *candidate)
{ {
unsigned char request[NETLINK_BUFFER_SIZE]; unsigned char request[NETLINK_BUFFER_SIZE];
struct nlmsghdr *hdr, *out, *current; struct nlmsghdr *hdr, *out, *current;
@@ -744,7 +745,12 @@ static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest,
chunk = dest->get_address(dest); chunk = dest->get_address(dest);
netlink_add_attribute(hdr, RTA_DST, chunk, sizeof(request)); netlink_add_attribute(hdr, RTA_DST, chunk, sizeof(request));
if (candidate)
{
chunk = candidate->get_address(candidate);
netlink_add_attribute(hdr, RTA_PREFSRC, chunk, sizeof(request));
}
if (this->socket->send(this->socket, hdr, &out, &len) != SUCCESS) if (this->socket->send(this->socket, hdr, &out, &len) != SUCCESS)
{ {
DBG1(DBG_KNL, "getting address to %H failed", dest); DBG1(DBG_KNL, "getting address to %H failed", dest);
@@ -878,9 +884,10 @@ static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest,
/** /**
* Implementation of kernel_net_t.get_source_addr. * Implementation of kernel_net_t.get_source_addr.
*/ */
static host_t* get_source_addr(private_kernel_netlink_net_t *this, host_t *dest) static host_t* get_source_addr(private_kernel_netlink_net_t *this,
host_t *dest, host_t *src)
{ {
return get_route(this, dest, FALSE); return get_route(this, dest, FALSE, src);
} }
/** /**
@@ -888,7 +895,7 @@ static host_t* get_source_addr(private_kernel_netlink_net_t *this, host_t *dest)
*/ */
static host_t* get_nexthop(private_kernel_netlink_net_t *this, host_t *dest) static host_t* get_nexthop(private_kernel_netlink_net_t *this, host_t *dest)
{ {
return get_route(this, dest, TRUE); return get_route(this, dest, TRUE, NULL);
} }
/** /**
@@ -1284,7 +1291,7 @@ kernel_netlink_net_t *kernel_netlink_net_create()
/* public functions */ /* public functions */
this->public.interface.get_interface = (char*(*)(kernel_net_t*,host_t*))get_interface_name; this->public.interface.get_interface = (char*(*)(kernel_net_t*,host_t*))get_interface_name;
this->public.interface.create_address_enumerator = (enumerator_t*(*)(kernel_net_t*,bool,bool))create_address_enumerator; this->public.interface.create_address_enumerator = (enumerator_t*(*)(kernel_net_t*,bool,bool))create_address_enumerator;
this->public.interface.get_source_addr = (host_t*(*)(kernel_net_t*, host_t *dest))get_source_addr; this->public.interface.get_source_addr = (host_t*(*)(kernel_net_t*, host_t *dest, host_t *src))get_source_addr;
this->public.interface.get_nexthop = (host_t*(*)(kernel_net_t*, host_t *dest))get_nexthop; this->public.interface.get_nexthop = (host_t*(*)(kernel_net_t*, host_t *dest))get_nexthop;
this->public.interface.add_ip = (status_t(*)(kernel_net_t*,host_t*,host_t*)) add_ip; this->public.interface.add_ip = (status_t(*)(kernel_net_t*,host_t*,host_t*)) add_ip;
this->public.interface.del_ip = (status_t(*)(kernel_net_t*,host_t*)) del_ip; this->public.interface.del_ip = (status_t(*)(kernel_net_t*,host_t*)) del_ip;
+13 -13
View File
@@ -1098,7 +1098,7 @@ static void resolve_hosts(private_ike_sa_t *this)
{ {
host->destroy(host); host->destroy(host);
host = charon->kernel_interface->get_source_addr( host = charon->kernel_interface->get_source_addr(
charon->kernel_interface, this->other_host); charon->kernel_interface, this->other_host, NULL);
if (host) if (host)
{ {
host->set_port(host, IKEV2_UDP_PORT); host->set_port(host, IKEV2_UDP_PORT);
@@ -2206,7 +2206,7 @@ static void set_auth_lifetime(private_ike_sa_t *this, u_int32_t lifetime)
*/ */
static status_t roam(private_ike_sa_t *this, bool address) static status_t roam(private_ike_sa_t *this, bool address)
{ {
host_t *me, *other; host_t *src;
ike_mobike_t *mobike; ike_mobike_t *mobike;
switch (this->state) switch (this->state)
@@ -2230,21 +2230,21 @@ static status_t roam(private_ike_sa_t *this, bool address)
return SUCCESS; return SUCCESS;
} }
/* get best address pair to use */ /* keep existing path if possible */
other = this->other_host; src = charon->kernel_interface->get_source_addr(charon->kernel_interface,
me = charon->kernel_interface->get_source_addr(charon->kernel_interface, this->other_host, this->my_host);
other); if (src)
if (me)
{ {
if (me->ip_equals(me, this->my_host) && if (src->ip_equals(src, this->my_host))
other->ip_equals(other, this->other_host))
{ {
DBG2(DBG_IKE, "keeping connection path %H - %H", this->other_host, me); DBG2(DBG_IKE, "keeping connection path %H - %H",
me->destroy(me); src, this->other_host);
src->destroy(src);
return SUCCESS; return SUCCESS;
} }
me->destroy(me); /* old address is not valid anymore, try with new one */
src->set_port(src, this->my_host->get_port(this->my_host));
set_my_host(this, src);
} }
/* update addresses with mobike, if supported ... */ /* update addresses with mobike, if supported ... */
+2 -2
View File
@@ -277,7 +277,7 @@ static void transmit(private_ike_mobike_t *this, packet_t *packet)
other_old = this->ike_sa->get_other_host(this->ike_sa); other_old = this->ike_sa->get_other_host(this->ike_sa);
me = charon->kernel_interface->get_source_addr( me = charon->kernel_interface->get_source_addr(
charon->kernel_interface, other_old); charon->kernel_interface, other_old, NULL);
if (me) if (me)
{ {
me->set_port(me, me->ip_equals(me, me_old) ? me->set_port(me, me->ip_equals(me, me_old) ?
@@ -289,7 +289,7 @@ static void transmit(private_ike_mobike_t *this, packet_t *packet)
while (iterator->iterate(iterator, (void**)&other)) while (iterator->iterate(iterator, (void**)&other))
{ {
me = charon->kernel_interface->get_source_addr( me = charon->kernel_interface->get_source_addr(
charon->kernel_interface, other); charon->kernel_interface, other, NULL);
if (me) if (me)
{ {
if (me->get_family(me) != other->get_family(other)) if (me->get_family(me) != other->get_family(other))
+2 -3
View File
@@ -341,9 +341,8 @@ static status_t build_i(private_ike_natd_t *this, message_t *message)
} }
else else
{ {
host = charon->kernel_interface->get_source_addr( host = charon->kernel_interface->get_source_addr(charon->kernel_interface,
charon->kernel_interface, this->ike_sa->get_other_host(this->ike_sa), NULL);
this->ike_sa->get_other_host(this->ike_sa));
if (host) if (host)
{ /* 2. */ { /* 2. */
host->set_port(host, IKEV2_UDP_PORT); host->set_port(host, IKEV2_UDP_PORT);