diff options
author | Tobias Brunner <tobias@strongswan.org> | 2011-09-09 16:07:40 +0200 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2012-09-21 18:16:25 +0200 |
commit | 9d6b02d6c16590de559a69eb1bcc74304dbaddf7 (patch) | |
tree | d878eb6b43bee0f1e46a061648b87248367e52ef /src | |
parent | da6d86dd94b9ab6611a2318aa08325d9e9182431 (diff) | |
download | strongswan-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.c | 39 |
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); |