Install virtual IPs via interface name, and use an interface lookup where required
authorMartin Willi <martin@revosec.ch>
Mon, 12 Nov 2012 09:06:09 +0000 (10:06 +0100)
committerMartin Willi <martin@revosec.ch>
Thu, 29 Nov 2012 09:22:51 +0000 (10:22 +0100)
src/frontends/android/jni/libandroidbridge/kernel/android_net.c
src/libcharon/plugins/load_tester/load_tester_config.c
src/libcharon/sa/child_sa.c
src/libcharon/sa/ike_sa.c
src/libhydra/kernel/kernel_interface.c
src/libhydra/kernel/kernel_interface.h
src/libhydra/kernel/kernel_net.h
src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c
src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c

index 8dc32e6..bc33959 100644 (file)
@@ -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;
index 1d678f1..7dc90c1 100644 (file)
@@ -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;
 }
 
index e1f244e..7083eb4 100644 (file)
@@ -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,
index 63c34c3..8585745 100644 (file)
@@ -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
index 2fbe848..733aced 100644 (file)
@@ -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,
index e3ebce8..a5ee0b5 100644 (file)
@@ -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.
index 50881ab..a6b7686 100644 (file)
@@ -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.
index 7db51fc..c00fa88 100644 (file)
@@ -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)
        {
index c53ec01..7311ded 100644 (file)
@@ -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;
 }