kernel-pfkey: Install routes with OUT policies
authorTobias Brunner <tobias@strongswan.org>
Fri, 10 Jun 2016 08:30:00 +0000 (10:30 +0200)
committerTobias Brunner <tobias@strongswan.org>
Fri, 10 Jun 2016 13:25:46 +0000 (15:25 +0200)
src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c

index b92a6e5..516a15a 100644 (file)
@@ -400,7 +400,7 @@ static void ipsec_sa_destroy(private_kernel_pfkey_ipsec_t *this,
 }
 
 typedef struct policy_sa_t policy_sa_t;
-typedef struct policy_sa_in_t policy_sa_in_t;
+typedef struct policy_sa_out_t policy_sa_out_t;
 
 /**
  * Mapping between a policy and an IPsec SA.
@@ -420,10 +420,10 @@ struct policy_sa_t {
 };
 
 /**
- * For input policies we also cache the traffic selectors in order to install
+ * For outbound policies we also cache the traffic selectors in order to install
  * the route.
  */
-struct policy_sa_in_t {
+struct policy_sa_out_t {
        /** Generic interface */
        policy_sa_t generic;
 
@@ -443,14 +443,14 @@ static policy_sa_t *policy_sa_create(private_kernel_pfkey_ipsec_t *this,
 {
        policy_sa_t *policy;
 
-       if (dir == POLICY_IN)
+       if (dir == POLICY_OUT)
        {
-               policy_sa_in_t *in;
-               INIT(in,
+               policy_sa_out_t *out;
+               INIT(out,
                        .src_ts = src_ts->clone(src_ts),
                        .dst_ts = dst_ts->clone(dst_ts),
                );
-               policy = &in->generic;
+               policy = &out->generic;
        }
        else
        {
@@ -467,11 +467,11 @@ static policy_sa_t *policy_sa_create(private_kernel_pfkey_ipsec_t *this,
 static void policy_sa_destroy(policy_sa_t *policy, policy_dir_t *dir,
                                                          private_kernel_pfkey_ipsec_t *this)
 {
-       if (*dir == POLICY_IN)
+       if (*dir == POLICY_OUT)
        {
-               policy_sa_in_t *in = (policy_sa_in_t*)policy;
-               in->src_ts->destroy(in->src_ts);
-               in->dst_ts->destroy(in->dst_ts);
+               policy_sa_out_t *out = (policy_sa_out_t*)policy;
+               out->src_ts->destroy(out->src_ts);
+               out->dst_ts->destroy(out->dst_ts);
        }
        ipsec_sa_destroy(this, policy->sa);
        free(policy);
@@ -2287,31 +2287,30 @@ static void remove_exclude_route(private_kernel_pfkey_ipsec_t *this,
 }
 
 /**
- * Try to install a route to the given inbound policy
+ * Try to install a route to the given outbound policy
  */
 static bool install_route(private_kernel_pfkey_ipsec_t *this,
-                                                 policy_entry_t *policy, policy_sa_in_t *in)
+                                                 policy_entry_t *policy, policy_sa_out_t *out)
 {
        route_entry_t *route, *old;
        host_t *host, *src, *dst;
        bool is_virtual;
 
-       if (charon->kernel->get_address_by_ts(charon->kernel, in->dst_ts, &host,
+       if (charon->kernel->get_address_by_ts(charon->kernel, out->src_ts, &host,
                                                                                  &is_virtual) != SUCCESS)
        {
                return FALSE;
        }
 
-       /* switch src/dst, as we handle an IN policy */
-       src = in->generic.sa->dst;
-       dst = in->generic.sa->src;
-
        INIT(route,
-               .prefixlen = policy->src.mask,
+               .prefixlen = policy->dst.mask,
                .src_ip = host,
-               .dst_net = chunk_clone(policy->src.net->get_address(policy->src.net)),
+               .dst_net = chunk_clone(policy->dst.net->get_address(policy->dst.net)),
        );
 
+       src = out->generic.sa->src;
+       dst = out->generic.sa->dst;
+
        if (!dst->is_anyaddr(dst))
        {
                route->gateway = charon->kernel->get_nexthop(charon->kernel, dst, -1,
@@ -2330,7 +2329,7 @@ static bool install_route(private_kernel_pfkey_ipsec_t *this,
        else
        {       /* for shunt policies */
                route->gateway = charon->kernel->get_nexthop(charon->kernel,
-                                                                                       policy->src.net, policy->src.mask,
+                                                                                       policy->dst.net, policy->dst.mask,
                                                                                        route->src_ip, &route->if_name);
 
                /* we don't have a source address, use the address we found */
@@ -2360,7 +2359,7 @@ static bool install_route(private_kernel_pfkey_ipsec_t *this,
                                                                          old->src_ip, old->if_name) != SUCCESS)
                {
                        DBG1(DBG_KNL, "error uninstalling route installed with policy "
-                                "%R === %R %N", in->src_ts, in->dst_ts,
+                                "%R === %R %N", out->src_ts, out->dst_ts,
                                policy_dir_names, policy->direction);
                }
                route_entry_destroy(old);
@@ -2370,22 +2369,22 @@ static bool install_route(private_kernel_pfkey_ipsec_t *this,
        /* if remote traffic selector covers the IKE peer, add an exclude route */
        if (charon->kernel->get_features(charon->kernel) & KERNEL_REQUIRE_EXCLUDE_ROUTE)
        {
-               if (in->src_ts->is_host(in->src_ts, dst))
+               if (out->dst_ts->is_host(out->dst_ts, dst))
                {
                        DBG1(DBG_KNL, "can't install route for %R === %R %N, conflicts "
-                                "with IKE traffic", in->src_ts, in->dst_ts, policy_dir_names,
+                                "with IKE traffic", out->src_ts, out->dst_ts, policy_dir_names,
                                 policy->direction);
                        route_entry_destroy(route);
                        return FALSE;
                }
-               if (in->src_ts->includes(in->src_ts, dst))
+               if (out->dst_ts->includes(out->dst_ts, dst))
                {
-                       add_exclude_route(this, route, in->generic.sa->dst, dst);
+                       add_exclude_route(this, route, out->generic.sa->src, dst);
                }
        }
 
        DBG2(DBG_KNL, "installing route: %R via %H src %H dev %s",
-                in->src_ts, route->gateway, route->src_ip, route->if_name);
+                out->dst_ts, route->gateway, route->src_ip, route->if_name);
 
        switch (charon->kernel->add_route(charon->kernel, route->dst_net,
                                                                          route->prefixlen, route->gateway,
@@ -2402,7 +2401,7 @@ static bool install_route(private_kernel_pfkey_ipsec_t *this,
                        return TRUE;
                default:
                        DBG1(DBG_KNL, "installing route failed: %R via %H src %H dev %s",
-                                in->src_ts, route->gateway, route->src_ip, route->if_name);
+                                out->dst_ts, route->gateway, route->src_ip, route->if_name);
                        remove_exclude_route(this, route);
                        route_entry_destroy(route);
                        return FALSE;
@@ -2559,12 +2558,12 @@ static status_t add_policy_internal(private_kernel_pfkey_ipsec_t *this,
        free(out);
 
        /* install a route, if:
-        * - this is an inbound policy (to just get one for each child)
+        * - this is an outbound policy (to just get one for each child)
         * - routing is not disabled via strongswan.conf
         * - the selector is not for a specific protocol/port
         * - we are in tunnel mode or install a bypass policy
         */
-       if (policy->direction == POLICY_IN && this->install_routes &&
+       if (policy->direction == POLICY_OUT && this->install_routes &&
                policy->src.proto == IPSEC_PROTO_ANY &&
                !policy->src.net->get_port(policy->src.net) &&
                !policy->dst.net->get_port(policy->dst.net))
@@ -2572,7 +2571,7 @@ static status_t add_policy_internal(private_kernel_pfkey_ipsec_t *this,
                if (mapping->type == POLICY_PASS ||
                   (mapping->type == POLICY_IPSEC && ipsec->cfg.mode != MODE_TRANSPORT))
                {
-                       install_route(this, policy, (policy_sa_in_t*)mapping);
+                       install_route(this, policy, (policy_sa_out_t*)mapping);
                }
        }
        this->mutex->unlock(this->mutex);