kernel-interface: get_address_by_ts() can tell if a returned IP is virtual
authorMartin Willi <martin@revosec.ch>
Fri, 19 Apr 2013 12:22:45 +0000 (14:22 +0200)
committerMartin Willi <martin@revosec.ch>
Mon, 6 May 2013 14:10:13 +0000 (16:10 +0200)
src/libhydra/kernel/kernel_interface.c
src/libhydra/kernel/kernel_interface.h
src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c
src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c

index 53b8324..290c25a 100644 (file)
@@ -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;
        }
index 1d2253b..f481043 100644 (file)
@@ -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.
index a120b3d..2d09d33 100644 (file)
@@ -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)
index 9a2e9f8..b30c953 100644 (file)
@@ -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(
index 650e16f..5d059cf 100644 (file)
@@ -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;
        }