diff --git a/src/frontends/android/jni/libandroidbridge/kernel/android_net.c b/src/frontends/android/jni/libandroidbridge/kernel/android_net.c index 8dc32e622..bc3395916 100644 --- a/src/frontends/android/jni/libandroidbridge/kernel/android_net.c +++ b/src/frontends/android/jni/libandroidbridge/kernel/android_net.c @@ -93,7 +93,7 @@ METHOD(kernel_net_t, get_source_addr, host_t*, METHOD(kernel_net_t, add_ip, status_t, private_kernel_android_net_t *this, host_t *virtual_ip, int prefix, - host_t *iface_ip) + char *iface) { /* we get the IP from the IKE_SA once the CHILD_SA is established */ return SUCCESS; diff --git a/src/libcharon/plugins/load_tester/load_tester_config.c b/src/libcharon/plugins/load_tester/load_tester_config.c index 1d678f1e5..7dc90c1f0 100644 --- a/src/libcharon/plugins/load_tester/load_tester_config.c +++ b/src/libcharon/plugins/load_tester/load_tester_config.c @@ -342,58 +342,42 @@ static void add_ts(char *string, child_cfg_t *cfg, bool local) */ static host_t *allocate_addr(private_load_tester_config_t *this, uint num) { - enumerator_t *pools, *addrs; + enumerator_t *enumerator; mem_pool_t *pool; - host_t *addr, *iface = NULL, *found = NULL, *requested; + host_t *found = NULL, *requested; identification_t *id; - char *name, buf[32]; + char *iface = NULL, buf[32]; requested = host_create_any(AF_INET); snprintf(buf, sizeof(buf), "ext-%d", num); id = identification_create_from_string(buf); - pools = this->pools->create_enumerator(this->pools); - while (!found && pools->enumerate(pools, &pool)) + enumerator = this->pools->create_enumerator(this->pools); + while (enumerator->enumerate(enumerator, &pool)) { - addrs = hydra->kernel_interface->create_address_enumerator( - hydra->kernel_interface, ADDR_TYPE_REGULAR); - while (!found && addrs->enumerate(addrs, &addr)) + found = pool->acquire_address(pool, id, requested, MEM_POOL_NEW); + if (found) { - if (hydra->kernel_interface->get_interface(hydra->kernel_interface, - addr, &name)) - { - if (streq(pool->get_name(pool), name)) - { - found = pool->acquire_address(pool, id, requested, - MEM_POOL_NEW); - if (found) - { - iface = addr->clone(addr); - } - } - free(name); - } + iface = (char*)pool->get_name(pool); + break; } - addrs->destroy(addrs); } - pools->destroy(pools); + enumerator->destroy(enumerator); requested->destroy(requested); id->destroy(id); if (!found) { - DBG1(DBG_CFG, "no interface found to install load-tester IP"); + DBG1(DBG_CFG, "no address found to install as load-tester external IP"); return NULL; } if (hydra->kernel_interface->add_ip(hydra->kernel_interface, found, this->prefix, iface) != SUCCESS) { - DBG1(DBG_CFG, "installing load-tester IP %H failed", found); - iface->destroy(iface); + DBG1(DBG_CFG, "installing load-tester IP %H on %s failed", found, iface); found->destroy(found); return NULL; } - DBG1(DBG_CFG, "installed load-tester IP %H", found); - iface->destroy(iface); + DBG1(DBG_CFG, "installed load-tester IP %H on %s", found, iface); return found; } diff --git a/src/libcharon/sa/child_sa.c b/src/libcharon/sa/child_sa.c index e1f244e7b..7083eb436 100644 --- a/src/libcharon/sa/child_sa.c +++ b/src/libcharon/sa/child_sa.c @@ -824,8 +824,15 @@ METHOD(child_sa_t, add_policies, status_t, */ static void reinstall_vip(host_t *vip, host_t *me) { - hydra->kernel_interface->del_ip(hydra->kernel_interface, vip, -1); - hydra->kernel_interface->add_ip(hydra->kernel_interface, vip, -1, me); + char *iface; + + if (hydra->kernel_interface->get_interface(hydra->kernel_interface, + me, &iface)) + { + hydra->kernel_interface->del_ip(hydra->kernel_interface, vip, -1); + hydra->kernel_interface->add_ip(hydra->kernel_interface, vip, -1, iface); + free(iface); + } } METHOD(child_sa_t, update, status_t, diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c index 63c34c3a5..858574567 100644 --- a/src/libcharon/sa/ike_sa.c +++ b/src/libcharon/sa/ike_sa.c @@ -741,15 +741,26 @@ METHOD(ike_sa_t, add_virtual_ip, void, { if (local) { - DBG1(DBG_IKE, "installing new virtual IP %H", ip); - if (hydra->kernel_interface->add_ip(hydra->kernel_interface, - ip, -1, this->my_host) == SUCCESS) + char *iface; + + if (hydra->kernel_interface->get_interface(hydra->kernel_interface, + this->my_host, &iface)) { - this->my_vips->insert_last(this->my_vips, ip->clone(ip)); + DBG1(DBG_IKE, "installing new virtual IP %H", ip); + if (hydra->kernel_interface->add_ip(hydra->kernel_interface, + ip, -1, iface) == SUCCESS) + { + this->my_vips->insert_last(this->my_vips, ip->clone(ip)); + } + else + { + DBG1(DBG_IKE, "installing virtual IP %H failed", ip); + } + free(iface); } else { - DBG1(DBG_IKE, "installing virtual IP %H failed", ip); + DBG1(DBG_IKE, "looking up interface for virtual IP %H failed", ip); } } else diff --git a/src/libhydra/kernel/kernel_interface.c b/src/libhydra/kernel/kernel_interface.c index 2fbe84818..733aced57 100644 --- a/src/libhydra/kernel/kernel_interface.c +++ b/src/libhydra/kernel/kernel_interface.c @@ -313,13 +313,13 @@ METHOD(kernel_interface_t, create_address_enumerator, enumerator_t*, METHOD(kernel_interface_t, add_ip, status_t, private_kernel_interface_t *this, host_t *virtual_ip, int prefix, - host_t *iface_ip) + char *iface) { if (!this->net) { return NOT_SUPPORTED; } - return this->net->add_ip(this->net, virtual_ip, prefix, iface_ip); + return this->net->add_ip(this->net, virtual_ip, prefix, iface); } METHOD(kernel_interface_t, del_ip, status_t, diff --git a/src/libhydra/kernel/kernel_interface.h b/src/libhydra/kernel/kernel_interface.h index e3ebce8ee..a5ee0b55b 100644 --- a/src/libhydra/kernel/kernel_interface.h +++ b/src/libhydra/kernel/kernel_interface.h @@ -333,15 +333,14 @@ struct kernel_interface_t { * Virtual IPs are attached to an interface. If an IP is added multiple * times, the IP is refcounted and not removed until del_ip() was called * as many times as add_ip(). - * The virtual IP is attached to the interface where the iface_ip is found. * * @param virtual_ip virtual ip address to assign * @param prefix prefix length to install IP with, -1 for auto - * @param iface_ip IP of an interface to attach virtual IP + * @param iface interface to install virtual IP on * @return SUCCESS if operation completed */ status_t (*add_ip) (kernel_interface_t *this, host_t *virtual_ip, int prefix, - host_t *iface_ip); + char *iface); /** * Remove a virtual IP from an interface. diff --git a/src/libhydra/kernel/kernel_net.h b/src/libhydra/kernel/kernel_net.h index 50881ab4d..a6b7686b0 100644 --- a/src/libhydra/kernel/kernel_net.h +++ b/src/libhydra/kernel/kernel_net.h @@ -112,15 +112,14 @@ struct kernel_net_t { * Virtual IPs are attached to an interface. If an IP is added multiple * times, the IP is refcounted and not removed until del_ip() was called * as many times as add_ip(). - * The virtual IP is attached to the interface where the iface_ip is found. * * @param virtual_ip virtual ip address to assign * @param prefix prefix length to install with IP address, -1 for auto - * @param iface_ip IP of an interface to attach virtual IP + * @param iface interface to install virtual IP on * @return SUCCESS if operation completed */ status_t (*add_ip) (kernel_net_t *this, host_t *virtual_ip, int prefix, - host_t *iface_ip); + char *iface); /** * Remove a virtual IP from an interface. diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c index 7db51fc85..c00fa8800 100644 --- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c +++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c @@ -1664,7 +1664,7 @@ static status_t manage_ipaddr(private_kernel_netlink_net_t *this, int nlmsg_type METHOD(kernel_net_t, add_ip, status_t, private_kernel_netlink_net_t *this, host_t *virtual_ip, int prefix, - host_t *iface_ip) + char *iface_name) { addr_map_entry_t *entry, lookup = { .ip = virtual_ip, @@ -1715,17 +1715,11 @@ METHOD(kernel_net_t, add_ip, status_t, this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_name, (void**)&iface, this->install_virtual_ip_on) != SUCCESS) { - lookup.ip = iface_ip; - entry = this->addrs->get_match(this->addrs, &lookup, - (void*)addr_map_entry_match); - if (!entry) + if (this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_name, + (void**)&iface, iface_name) != SUCCESS) { /* if we don't find the requested interface we just use the first */ this->ifaces->get_first(this->ifaces, (void**)&iface); } - else - { - iface = entry->iface; - } } if (iface) { diff --git a/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c b/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c index c53ec010c..7311ded0f 100644 --- a/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c +++ b/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c @@ -641,7 +641,7 @@ METHOD(kernel_net_t, get_nexthop, host_t*, METHOD(kernel_net_t, add_ip, status_t, private_kernel_pfroute_net_t *this, host_t *virtual_ip, int prefix, - host_t *iface_ip) + char *iface) { return FAILED; }