Make it easy to check if an address is locally usable via changed get_interface(...
authorTobias Brunner <tobias@strongswan.org>
Fri, 14 Sep 2012 14:27:33 +0000 (16:27 +0200)
committerTobias Brunner <tobias@strongswan.org>
Fri, 21 Sep 2012 16:16:26 +0000 (18:16 +0200)
src/libcharon/plugins/stroke/stroke_config.c
src/libcharon/plugins/updown/updown_listener.c
src/libhydra/kernel/kernel_interface.c
src/libhydra/kernel/kernel_interface.h
src/libhydra/kernel/kernel_net.h
src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c
src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c
src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c

index da3459b..e43672b 100644 (file)
@@ -191,42 +191,34 @@ static ike_cfg_t *build_ike_cfg(private_stroke_config_t *this, stroke_msg_t *msg
 {
        stroke_end_t tmp_end;
        ike_cfg_t *ike_cfg;
-       char *interface;
        host_t *host;
        u_int16_t ikeport;
 
        host = host_create_from_dns(msg->add_conn.other.address, 0, 0);
        if (host)
        {
-               interface = hydra->kernel_interface->get_interface(
-                                                                                               hydra->kernel_interface, host);
-               host->destroy(host);
-               if (interface)
+               if (hydra->kernel_interface->get_interface(hydra->kernel_interface,
+                                                                                                  host, NULL))
                {
                        DBG2(DBG_CFG, "left is other host, swapping ends");
                        tmp_end = msg->add_conn.me;
                        msg->add_conn.me = msg->add_conn.other;
                        msg->add_conn.other = tmp_end;
-                       free(interface);
+                       host->destroy(host);
                }
                else
                {
+                       host->destroy(host);
                        host = host_create_from_dns(msg->add_conn.me.address, 0, 0);
                        if (host)
                        {
-                               interface = hydra->kernel_interface->get_interface(
-                                                                                               hydra->kernel_interface, host);
-                               host->destroy(host);
-                               if (!interface)
+                               if (!hydra->kernel_interface->get_interface(
+                                                                               hydra->kernel_interface, host, NULL))
                                {
                                        DBG1(DBG_CFG, "left nor right host is our side, "
                                                 "assuming left=local");
                                }
-                               else
-                               {
-                                       free(interface);
-                               }
-
+                               host->destroy(host);
                        }
                }
        }
index 2f9f2ef..8b2af05 100644 (file)
@@ -267,9 +267,8 @@ METHOD(listener_t, child_updown, bool,
 
                if (up)
                {
-                       iface = hydra->kernel_interface->get_interface(
-                                                                                               hydra->kernel_interface, me);
-                       if (iface)
+                       if (hydra->kernel_interface->get_interface(hydra->kernel_interface,
+                                                                                                          me, &iface))
                        {
                                cache_iface(this, child_sa->get_reqid(child_sa), iface);
                        }
index 8e3f6a6..7bdc0be 100644 (file)
@@ -291,14 +291,14 @@ METHOD(kernel_interface_t, get_nexthop, host_t*,
        return this->net->get_nexthop(this->net, dest, src);
 }
 
-METHOD(kernel_interface_t, get_interface, char*,
-       private_kernel_interface_t *this, host_t *host)
+METHOD(kernel_interface_t, get_interface, bool,
+       private_kernel_interface_t *this, host_t *host, char **name)
 {
        if (!this->net)
        {
                return NULL;
        }
-       return this->net->get_interface(this->net, host);
+       return this->net->get_interface(this->net, host, name);
 }
 
 METHOD(kernel_interface_t, create_address_enumerator, enumerator_t*,
index 5396dad..842b511 100644 (file)
@@ -308,9 +308,10 @@ struct kernel_interface_t {
         * Get the interface name of a local address.
         *
         * @param host                  address to get interface name from
-        * @return                              allocated interface name, or NULL if not found
+        * @param name                  allocated interface name (optional)
+        * @return                              TRUE if interface found and usable
         */
-       char* (*get_interface) (kernel_interface_t *this, host_t *host);
+       bool (*get_interface) (kernel_interface_t *this, host_t *host, char **name);
 
        /**
         * Creates an enumerator over all local addresses.
index 772ccac..4edd8da 100644 (file)
@@ -68,9 +68,10 @@ struct kernel_net_t {
         * Get the interface name of a local address.
         *
         * @param host                  address to get interface name from
-        * @return                              allocated interface name, or NULL if not found
+        * @param name                  allocated interface name (optional)
+        * @return                              TRUE if interface found and usable
         */
-       char* (*get_interface) (kernel_net_t *this, host_t *host);
+       bool (*get_interface) (kernel_net_t *this, host_t *host, char **name);
 
        /**
         * Creates an enumerator over all local addresses.
index ac1122d..d875dab 100644 (file)
@@ -2108,7 +2108,7 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
         */
        if (policy->route == NULL && direction == POLICY_OUT)
        {
-               char *iface;
+               char *iface = NULL;
                ipsec_dev_t *dev;
                route_entry_t *route = malloc_thing(route_entry_t);
                route->src_ip = NULL;
@@ -2126,8 +2126,8 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
                }
 
                /* find the virtual interface */
-               iface = hydra->kernel_interface->get_interface(hydra->kernel_interface,
-                                                                                                          src);
+               hydra->kernel_interface->get_interface(hydra->kernel_interface,
+                                                                                          src, &iface);
                if (find_ipsec_dev(this, iface, &dev) == SUCCESS)
                {
                        /* above, we got either the name of a virtual or a physical
index 31ca717..cfd85a5 100644 (file)
@@ -2169,14 +2169,13 @@ static status_t add_policy_internal(private_kernel_netlink_ipsec_t *this,
                        route->gateway = hydra->kernel_interface->get_nexthop(
                                                                                        hydra->kernel_interface, ipsec->src,
                                                                                        ipsec->dst);
-                       /* install route via outgoing interface */
-                       route->if_name = hydra->kernel_interface->get_interface(
-                                                                               hydra->kernel_interface, ipsec->dst);
                        route->dst_net = chunk_alloc(policy->sel.family == AF_INET ? 4 : 16);
                        memcpy(route->dst_net.ptr, &policy->sel.saddr, route->dst_net.len);
                        route->prefixlen = policy->sel.prefixlen_s;
 
-                       if (!route->if_name)
+                       /* install route via outgoing interface */
+                       if (!hydra->kernel_interface->get_interface(hydra->kernel_interface,
+                                                                                               ipsec->dst, &route->if_name))
                        {
                                this->mutex->unlock(this->mutex);
                                route_entry_destroy(route);
index 52671a2..b4eabb2 100644 (file)
@@ -365,13 +365,15 @@ static job_requeue_t reinstall_routes(private_kernel_netlink_net_t *this)
                change = this->net_changes->get(this->net_changes, &lookup);
                if (!change)
                {       /* in case src_ip is not on the outgoing interface */
-                       lookup.if_name = this->public.interface.get_interface(
-                                                                               &this->public.interface, route->src_ip);
-                       if (lookup.if_name && !streq(lookup.if_name, route->if_name))
+                       if (this->public.interface.get_interface(&this->public.interface,
+                                                                                               route->src_ip, &lookup.if_name))
                        {
-                               change = this->net_changes->get(this->net_changes, &lookup);
+                               if (!streq(lookup.if_name, route->if_name))
+                               {
+                                       change = this->net_changes->get(this->net_changes, &lookup);
+                               }
+                               free(lookup.if_name);
                        }
-                       free(lookup.if_name);
                }
                if (change)
                {
@@ -999,15 +1001,13 @@ METHOD(kernel_net_t, create_address_enumerator, enumerator_t*,
                                (void*)address_enumerator_destroy);
 }
 
-METHOD(kernel_net_t, get_interface_name, char*,
-       private_kernel_netlink_net_t *this, host_t* ip)
+METHOD(kernel_net_t, get_interface_name, bool,
+       private_kernel_netlink_net_t *this, host_t* ip, char **name)
 {
        enumerator_t *ifaces, *addrs;
        iface_entry_t *iface;
        addr_entry_t *addr;
-       char *name = NULL;
-
-       DBG2(DBG_KNL, "getting interface name for %H", ip);
+       bool found = FALSE;
 
        this->mutex->lock(this->mutex);
        ifaces = this->ifaces->create_enumerator(this->ifaces);
@@ -1018,12 +1018,16 @@ METHOD(kernel_net_t, get_interface_name, char*,
                {
                        if (ip->ip_equals(ip, addr->ip))
                        {
-                               name = strdup(iface->ifname);
+                               found = TRUE;
+                               if (name)
+                               {
+                                       *name = strdup(iface->ifname);
+                               }
                                break;
                        }
                }
                addrs->destroy(addrs);
-               if (name)
+               if (found)
                {
                        break;
                }
@@ -1031,15 +1035,15 @@ METHOD(kernel_net_t, get_interface_name, char*,
        ifaces->destroy(ifaces);
        this->mutex->unlock(this->mutex);
 
-       if (name)
+       if (!found)
        {
-               DBG2(DBG_KNL, "%H is on interface %s", ip, name);
+               DBG2(DBG_KNL, "%H is not a local address", ip);
        }
-       else
+       else if (name)
        {
-               DBG2(DBG_KNL, "%H is not a local address", ip);
+               DBG2(DBG_KNL, "%H is on interface %s", ip, *name);
        }
-       return name;
+       return found;
 }
 
 /**
index 4ecb727..14ca4c8 100644 (file)
@@ -2028,14 +2028,13 @@ static status_t add_policy_internal(private_kernel_pfkey_ipsec_t *this,
                        route->gateway = hydra->kernel_interface->get_nexthop(
                                                                                        hydra->kernel_interface, ipsec->src,
                                                                                        ipsec->dst);
-                       /* install route via outgoing interface */
-                       route->if_name = hydra->kernel_interface->get_interface(
-                                                                               hydra->kernel_interface, ipsec->dst);
                        route->dst_net = chunk_clone(policy->src.net->get_address(
                                                                                        policy->src.net));
                        route->prefixlen = policy->src.mask;
 
-                       if (!route->if_name)
+                       /* install route via outgoing interface */
+                       if (!hydra->kernel_interface->get_interface(hydra->kernel_interface,
+                                                                                               ipsec->dst, &route->if_name))
                        {
                                this->mutex->unlock(this->mutex);
                                route_entry_destroy(route);
index 8785737..d24820c 100644 (file)
@@ -472,15 +472,13 @@ METHOD(kernel_net_t, create_address_enumerator, enumerator_t*,
                                (void*)address_enumerator_destroy);
 }
 
-METHOD(kernel_net_t, get_interface_name, char*,
-       private_kernel_pfroute_net_t *this, host_t* ip)
+METHOD(kernel_net_t, get_interface_name, bool,
+       private_kernel_pfroute_net_t *this, host_t* ip, char **name)
 {
        enumerator_t *ifaces, *addrs;
        iface_entry_t *iface;
        addr_entry_t *addr;
-       char *name = NULL;
-
-       DBG2(DBG_KNL, "getting interface name for %H", ip);
+       bool found = FALSE;
 
        this->mutex->lock(this->mutex);
        ifaces = this->ifaces->create_enumerator(this->ifaces);
@@ -491,12 +489,16 @@ METHOD(kernel_net_t, get_interface_name, char*,
                {
                        if (ip->ip_equals(ip, addr->ip))
                        {
-                               name = strdup(iface->ifname);
+                               found = TRUE;
+                               if (name)
+                               {
+                                       *name = strdup(iface->ifname);
+                               }
                                break;
                        }
                }
                addrs->destroy(addrs);
-               if (name)
+               if (found)
                {
                        break;
                }
@@ -504,15 +506,15 @@ METHOD(kernel_net_t, get_interface_name, char*,
        ifaces->destroy(ifaces);
        this->mutex->unlock(this->mutex);
 
-       if (name)
+       if (!found)
        {
-               DBG2(DBG_KNL, "%H is on interface %s", ip, name);
+               DBG2(DBG_KNL, "%H is not a local address", ip);
        }
-       else
+       else if (name)
        {
-               DBG2(DBG_KNL, "%H is not a local address", ip);
+               DBG2(DBG_KNL, "%H is on interface %s", ip, *name);
        }
-       return name;
+       return found;
 }
 
 METHOD(kernel_net_t, get_source_addr, host_t*,