From f52cf07532dded002c073db69c11e0c891e27bf5 Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Fri, 19 Apr 2013 14:22:45 +0200 Subject: [PATCH] kernel-interface: get_address_by_ts() can tell if a returned IP is virtual --- src/libhydra/kernel/kernel_interface.c | 28 ++++++++++++++++++++-- src/libhydra/kernel/kernel_interface.h | 3 ++- .../plugins/kernel_klips/kernel_klips_ipsec.c | 2 +- .../plugins/kernel_netlink/kernel_netlink_ipsec.c | 2 +- .../plugins/kernel_pfkey/kernel_pfkey_ipsec.c | 2 +- 5 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/libhydra/kernel/kernel_interface.c b/src/libhydra/kernel/kernel_interface.c index 53b8324..290c25a 100644 --- a/src/libhydra/kernel/kernel_interface.c +++ b/src/libhydra/kernel/kernel_interface.c @@ -415,7 +415,8 @@ METHOD(kernel_interface_t, all_interfaces_usable, bool, } METHOD(kernel_interface_t, get_address_by_ts, status_t, - private_kernel_interface_t *this, traffic_selector_t *ts, host_t **ip) + private_kernel_interface_t *this, traffic_selector_t *ts, + host_t **ip, bool *vip) { enumerator_t *addrs; host_t *host; @@ -446,13 +447,17 @@ METHOD(kernel_interface_t, get_address_by_ts, status_t, } host->destroy(host); - addrs = create_address_enumerator(this, ADDR_TYPE_ALL); + addrs = create_address_enumerator(this, ADDR_TYPE_VIRTUAL); while (addrs->enumerate(addrs, (void**)&host)) { if (ts->includes(ts, host)) { found = TRUE; *ip = host->clone(host); + if (vip) + { + *vip = TRUE; + } break; } } @@ -460,6 +465,25 @@ METHOD(kernel_interface_t, get_address_by_ts, status_t, if (!found) { + addrs = create_address_enumerator(this, ADDR_TYPE_REGULAR); + while (addrs->enumerate(addrs, (void**)&host)) + { + if (ts->includes(ts, host)) + { + found = TRUE; + *ip = host->clone(host); + if (vip) + { + *vip = FALSE; + } + break; + } + } + addrs->destroy(addrs); + } + + if (!found) + { DBG2(DBG_KNL, "no local address found in traffic selector %R", ts); return FAILED; } diff --git a/src/libhydra/kernel/kernel_interface.h b/src/libhydra/kernel/kernel_interface.h index 1d2253b..f481043 100644 --- a/src/libhydra/kernel/kernel_interface.h +++ b/src/libhydra/kernel/kernel_interface.h @@ -451,10 +451,11 @@ struct kernel_interface_t { * * @param ts traffic selector * @param ip returned IP address (has to be destroyed) + * @param vip set to TRUE if returned address is a virtual IP * @return SUCCESS if address found */ status_t (*get_address_by_ts)(kernel_interface_t *this, - traffic_selector_t *ts, host_t **ip); + traffic_selector_t *ts, host_t **ip, bool *vip); /** * Register an ipsec kernel interface constructor on the manager. diff --git a/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c b/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c index a120b3d..2d09d33 100644 --- a/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c +++ b/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c @@ -2118,7 +2118,7 @@ METHOD(kernel_ipsec_t, add_policy, status_t, this->install_routes) { hydra->kernel_interface->get_address_by_ts(hydra->kernel_interface, - src_ts, &route->src_ip); + src_ts, &route->src_ip, NULL); } if (!route->src_ip) diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c index 9a2e9f8..b30c953 100644 --- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c +++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c @@ -2102,7 +2102,7 @@ static status_t add_policy_internal(private_kernel_netlink_ipsec_t *this, ); if (hydra->kernel_interface->get_address_by_ts(hydra->kernel_interface, - fwd->dst_ts, &route->src_ip) == SUCCESS) + fwd->dst_ts, &route->src_ip, NULL) == SUCCESS) { /* get the nexthop to src (src as we are in POLICY_FWD) */ route->gateway = hydra->kernel_interface->get_nexthop( diff --git a/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c index 650e16f..5d059cf 100644 --- a/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c +++ b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c @@ -1925,7 +1925,7 @@ static bool install_route(private_kernel_pfkey_ipsec_t *this, host_t *host, *src, *dst; if (hydra->kernel_interface->get_address_by_ts(hydra->kernel_interface, - in->dst_ts, &host) != SUCCESS) + in->dst_ts, &host, NULL) != SUCCESS) { return FALSE; } -- 2.7.4