aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2011-09-09 16:07:40 +0200
committerTobias Brunner <tobias@strongswan.org>2012-09-21 18:16:25 +0200
commit9d6b02d6c16590de559a69eb1bcc74304dbaddf7 (patch)
treed878eb6b43bee0f1e46a061648b87248367e52ef /src
parentda6d86dd94b9ab6611a2318aa08325d9e9182431 (diff)
downloadstrongswan-9d6b02d6c16590de559a69eb1bcc74304dbaddf7.tar.bz2
strongswan-9d6b02d6c16590de559a69eb1bcc74304dbaddf7.tar.xz
Try to find preferred source on interface if returned source does not match
Diffstat (limited to 'src')
-rw-r--r--src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c39
1 files changed, 29 insertions, 10 deletions
diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c
index d845a0f02..73d7ed2c9 100644
--- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c
+++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c
@@ -1276,26 +1276,45 @@ static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest,
best = msg->rtm_dst_len;
continue;
}
+
+ /* try to find an appropriate source address */
if (rta_src.ptr)
- { /* got a source address */
- new_src = host_create_from_chunk(msg->rtm_family, rta_src, 0);
+ { /* got a source address with the route */
+ new_src = host_create_from_chunk(msg->rtm_family,
+ rta_src, 0);
if (new_src)
{
if (get_vip_refcount(this, new_src))
- { /* skip source address if it is installed by us */
+ { /* skip route if it is installed by us */
new_src->destroy(new_src);
+ continue;
}
- else
- {
- DESTROY_IF(src);
- src = new_src;
- best = msg->rtm_dst_len;
+ DESTROY_IF(src);
+ src = new_src;
+ if (candidate && !src->ip_equals(src, candidate) &&
+ rta_oif)
+ { /* this source does not match our preferred source.
+ * but maybe it is assigned to the same iface */
+ new_src = get_interface_address(this, rta_oif,
+ msg->rtm_family,
+ candidate);
+ if (new_src &&
+ new_src->ip_equals(new_src, candidate))
+ {
+ DESTROY_IF(src);
+ src = new_src;
+ }
+ else
+ {
+ DESTROY_IF(new_src);
+ }
}
+ best = msg->rtm_dst_len;
}
continue;
}
if (rta_oif)
- { /* no src or gtw, but an interface. Get address from it. */
+ { /* no src, but an interface - get address from it */
new_src = get_interface_address(this, rta_oif,
msg->rtm_family, candidate);
if (new_src)
@@ -1307,7 +1326,7 @@ static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest,
continue;
}
if (rta_gtw.ptr)
- { /* no source, but a gateway. Lookup source to reach gtw. */
+ { /* no src, but a gateway - lookup src to reach gtw */
new_gtw = host_create_from_chunk(msg->rtm_family, rta_gtw, 0);
new_src = get_route(this, new_gtw, FALSE, candidate);
new_gtw->destroy(new_gtw);