kernel-netlink: Implement passthrough type routes and use them on Linux
authorNoel Kuntze <noel@familie-kuntze.de>
Sun, 9 Feb 2020 13:52:32 +0000 (14:52 +0100)
committerTobias Brunner <tobias@strongswan.org>
Tue, 10 Mar 2020 09:20:58 +0000 (10:20 +0100)
Enables us to ignore any future kernel features for routes unless
we actually need to consider them for the source IP routes.

Also enables us to actually really skip IPsec processing for those networks
(because even the routes don't touch those packets). It's more what
users expect.

Co-authored-by: Tobias Brunner <tobias@strongswan.org>
src/frontends/android/app/src/main/jni/libandroidbridge/kernel/android_net.c
src/libcharon/kernel/kernel_interface.c
src/libcharon/kernel/kernel_interface.h
src/libcharon/kernel/kernel_net.h
src/libcharon/plugins/kernel_iph/kernel_iph_net.c
src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c
src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c
src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c
src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c
src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c

index 3a31204..cc60722 100644 (file)
@@ -256,14 +256,14 @@ METHOD(kernel_net_t, del_ip, status_t,
 
 METHOD(kernel_net_t, add_route, status_t,
        private_android_net_t *this, chunk_t dst_net, uint8_t prefixlen,
-       host_t *gateway, host_t *src_ip, char *if_name)
+       host_t *gateway, host_t *src_ip, char *if_name, bool pass)
 {
        return NOT_SUPPORTED;
 }
 
 METHOD(kernel_net_t, del_route, status_t,
        private_android_net_t *this, chunk_t dst_net, uint8_t prefixlen,
-       host_t *gateway, host_t *src_ip, char *if_name)
+       host_t *gateway, host_t *src_ip, char *if_name, bool pass)
 {
        return NOT_SUPPORTED;
 }
index ced026d..300796f 100644 (file)
@@ -614,26 +614,28 @@ METHOD(kernel_interface_t, del_ip, status_t,
 
 METHOD(kernel_interface_t, add_route, status_t,
        private_kernel_interface_t *this, chunk_t dst_net,
-       uint8_t prefixlen, host_t *gateway, host_t *src_ip, char *if_name)
+       uint8_t prefixlen, host_t *gateway, host_t *src_ip, char *if_name,
+       bool pass)
 {
        if (!this->net)
        {
                return NOT_SUPPORTED;
        }
        return this->net->add_route(this->net, dst_net, prefixlen, gateway,
-                                                               src_ip, if_name);
+                                                               src_ip, if_name, pass);
 }
 
 METHOD(kernel_interface_t, del_route, status_t,
        private_kernel_interface_t *this, chunk_t dst_net,
-       uint8_t prefixlen, host_t *gateway, host_t *src_ip, char *if_name)
+       uint8_t prefixlen, host_t *gateway, host_t *src_ip, char *if_name,
+       bool pass)
 {
        if (!this->net)
        {
                return NOT_SUPPORTED;
        }
        return this->net->del_route(this->net, dst_net, prefixlen, gateway,
-                                                               src_ip, if_name);
+                                                               src_ip, if_name, pass);
 }
 
 METHOD(kernel_interface_t, bypass_socket, bool,
index 141198a..50c1cac 100644 (file)
@@ -375,12 +375,13 @@ struct kernel_interface_t {
         * @param gateway               gateway for this route
         * @param src_ip                source ip of the route
         * @param if_name               name of the interface the route is bound to
+        * @param pass                  TRUE if route is installed for passthrough policy
         * @return                              SUCCESS if operation completed
         *                                              ALREADY_DONE if the route already exists
         */
        status_t (*add_route) (kernel_interface_t *this, chunk_t dst_net,
                                                   uint8_t prefixlen, host_t *gateway, host_t *src_ip,
-                                                  char *if_name);
+                                                  char *if_name, bool pass);
 
        /**
         * Delete a route.
@@ -390,11 +391,12 @@ struct kernel_interface_t {
         * @param gateway               gateway for this route
         * @param src_ip                source ip of the route
         * @param if_name               name of the interface the route is bound to
+        * @param pass                  TRUE if route was installed for passthrough policy
         * @return                              SUCCESS if operation completed
         */
        status_t (*del_route) (kernel_interface_t *this, chunk_t dst_net,
                                                   uint8_t prefixlen, host_t *gateway, host_t *src_ip,
-                                                  char *if_name);
+                                                  char *if_name, bool pass);
 
        /**
         * Set up a bypass policy for a given socket.
index 12475b1..11e1970 100644 (file)
@@ -165,12 +165,13 @@ struct kernel_net_t {
         * @param gateway               gateway for this route
         * @param src_ip                source ip of the route
         * @param if_name               name of the interface the route is bound to
+        * @param pass                  TRUE if route is installed for passthrough policy
         * @return                              SUCCESS if operation completed
         *                                              ALREADY_DONE if the route already exists
         */
        status_t (*add_route) (kernel_net_t *this, chunk_t dst_net,
                                                   uint8_t prefixlen, host_t *gateway, host_t *src_ip,
-                                                  char *if_name);
+                                                  char *if_name, bool pass);
 
        /**
         * Delete a route.
@@ -180,11 +181,12 @@ struct kernel_net_t {
         * @param gateway               gateway for this route
         * @param src_ip                source ip of the route
         * @param if_name               name of the interface the route is bound to
+        * @param pass                  TRUE if route was installed for passthrough policy
         * @return                              SUCCESS if operation completed
         */
        status_t (*del_route) (kernel_net_t *this, chunk_t dst_net,
                                                   uint8_t prefixlen, host_t *gateway, host_t *src_ip,
-                                                  char *if_name);
+                                                  char *if_name, bool pass);
 
        /**
         * Destroy the implementation.
index 18a87b7..6b5d824 100644 (file)
@@ -715,14 +715,14 @@ static status_t manage_route(private_kernel_iph_net_t *this, bool add,
 
 METHOD(kernel_net_t, add_route, status_t,
        private_kernel_iph_net_t *this, chunk_t dst, uint8_t prefixlen,
-       host_t *gateway, host_t *src, char *name)
+       host_t *gateway, host_t *src, char *name, bool pass)
 {
        return manage_route(this, TRUE, dst, prefixlen, gateway, name);
 }
 
 METHOD(kernel_net_t, del_route, status_t,
        private_kernel_iph_net_t *this, chunk_t dst, uint8_t prefixlen,
-       host_t *gateway, host_t *src, char *name)
+       host_t *gateway, host_t *src, char *name, bool pass)
 {
        return manage_route(this, FALSE, dst, prefixlen, gateway, name);
 }
index 3665d45..4c2933a 100644 (file)
@@ -315,7 +315,7 @@ static void add_exclude_route(private_kernel_libipsec_ipsec_t *this,
                        if (charon->kernel->get_interface(charon->kernel, src, &if_name) &&
                                charon->kernel->add_route(charon->kernel, dst->get_address(dst),
                                                                        dst->get_family(dst) == AF_INET ? 32 : 128,
-                                                                       gtw, src, if_name) == SUCCESS)
+                                                                       gtw, src, if_name, TRUE) == SUCCESS)
                        {
                                INIT(exclude,
                                        .dst = dst->clone(dst),
@@ -363,7 +363,7 @@ static void remove_exclude_route(private_kernel_libipsec_ipsec_t *this,
                charon->kernel->del_route(charon->kernel, dst->get_address(dst),
                                                                  dst->get_family(dst) == AF_INET ? 32 : 128,
                                                                  route->exclude->gtw, route->exclude->src,
-                                                                 if_name) != SUCCESS)
+                                                                 if_name, TRUE) != SUCCESS)
        {
                DBG1(DBG_KNL, "uninstalling exclude route for %H failed", dst);
        }
@@ -449,8 +449,8 @@ static bool install_route(private_kernel_libipsec_ipsec_t *this,
                }
                /* uninstall previously installed route */
                if (charon->kernel->del_route(charon->kernel, old->dst_net,
-                                                                         old->prefixlen, old->gateway,
-                                                                         old->src_ip, old->if_name) != SUCCESS)
+                                                                         old->prefixlen, old->gateway, old->src_ip,
+                                                                         old->if_name, FALSE) != SUCCESS)
                {
                        DBG1(DBG_KNL, "error uninstalling route installed with policy "
                                 "%R === %R %N", src_ts, dst_ts, policy_dir_names,
@@ -481,7 +481,7 @@ static bool install_route(private_kernel_libipsec_ipsec_t *this,
 
        switch (charon->kernel->add_route(charon->kernel, route->dst_net,
                                                                          route->prefixlen, route->gateway,
-                                                                         route->src_ip, route->if_name))
+                                                                         route->src_ip, route->if_name, FALSE))
        {
                case ALREADY_DONE:
                        /* route exists, do not uninstall */
@@ -586,8 +586,8 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
                route_entry_t *route = policy->route;
 
                if (charon->kernel->del_route(charon->kernel, route->dst_net,
-                                                                         route->prefixlen, route->gateway,
-                                                                         route->src_ip, route->if_name) != SUCCESS)
+                                                               route->prefixlen, route->gateway, route->src_ip,
+                                                               route->if_name, FALSE) != SUCCESS)
                {
                        DBG1(DBG_KNL, "error uninstalling route installed with "
                                 "policy %R === %R %N", id->src_ts, id->dst_ts,
@@ -618,7 +618,7 @@ METHOD(kernel_ipsec_t, flush_policies, status_t,
 
                        charon->kernel->del_route(charon->kernel, route->dst_net,
                                                                          route->prefixlen, route->gateway,
-                                                                         route->src_ip, route->if_name);
+                                                                         route->src_ip, route->if_name, FALSE);
                        remove_exclude_route(this, route);
                }
                policy_entry_destroy(pol);
index 327854f..9a91549 100644 (file)
@@ -390,6 +390,9 @@ struct route_entry_t {
 
        /** Destination net prefixlen */
        uint8_t prefixlen;
+
+       /** Whether the route was installed for a passthrough policy */
+       bool pass;
 };
 
 /**
@@ -410,6 +413,7 @@ static void route_entry_destroy(route_entry_t *this)
 static bool route_entry_equals(route_entry_t *a, route_entry_t *b)
 {
        if (a->if_name && b->if_name && streq(a->if_name, b->if_name) &&
+               a->pass == b->pass &&
                a->src_ip->ip_equals(a->src_ip, b->src_ip) &&
                chunk_equals(a->dst_net, b->dst_net) && a->prefixlen == b->prefixlen)
        {
@@ -2614,6 +2618,7 @@ static void install_route(private_kernel_netlink_ipsec_t *this,
 
        INIT(route,
                .prefixlen = policy->sel.prefixlen_d,
+               .pass = mapping->type == POLICY_PASS,
        );
 
        if (charon->kernel->get_address_by_ts(charon->kernel, out->src_ts,
@@ -2664,7 +2669,8 @@ static void install_route(private_kernel_netlink_ipsec_t *this,
                        /* uninstall previously installed route */
                        if (charon->kernel->del_route(charon->kernel, old->dst_net,
                                                                                  old->prefixlen, old->gateway,
-                                                                                 old->src_ip, old->if_name) != SUCCESS)
+                                                                                 old->src_ip, old->if_name,
+                                                                                 old->pass) != SUCCESS)
                        {
                                DBG1(DBG_KNL, "error uninstalling route installed with policy "
                                         "%R === %R %N", out->src_ts, out->dst_ts, policy_dir_names,
@@ -2678,7 +2684,8 @@ static void install_route(private_kernel_netlink_ipsec_t *this,
                         route->gateway, route->src_ip, route->if_name);
                switch (charon->kernel->add_route(charon->kernel, route->dst_net,
                                                                                  route->prefixlen, route->gateway,
-                                                                                 route->src_ip, route->if_name))
+                                                                                 route->src_ip, route->if_name,
+                                                                                 route->pass))
                {
                        default:
                                DBG1(DBG_KNL, "unable to install source route for %H",
@@ -3207,7 +3214,8 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
                route_entry_t *route = current->route;
                if (charon->kernel->del_route(charon->kernel, route->dst_net,
                                                                          route->prefixlen, route->gateway,
-                                                                         route->src_ip, route->if_name) != SUCCESS)
+                                                                         route->src_ip, route->if_name,
+                                                                         route->pass) != SUCCESS)
                {
                        DBG1(DBG_KNL, "error uninstalling route installed with policy "
                                 "%R === %R %N%s", id->src_ts, id->dst_ts, policy_dir_names,
index f95ee3c..24d93cc 100644 (file)
@@ -286,6 +286,9 @@ struct route_entry_t {
 
        /** Destination net prefixlen */
        uint8_t prefixlen;
+
+       /** Whether the route was installed for a passthrough policy */
+       bool pass;
 };
 
 /**
@@ -301,6 +304,7 @@ static route_entry_t *route_entry_clone(route_entry_t *this)
                .gateway = this->gateway ? this->gateway->clone(this->gateway) : NULL,
                .dst_net = chunk_clone(this->dst_net),
                .prefixlen = this->prefixlen,
+               .pass = this->pass,
        );
        return route;
 }
@@ -332,6 +336,7 @@ static u_int route_entry_hash(route_entry_t *this)
 static bool route_entry_equals(route_entry_t *a, route_entry_t *b)
 {
        if (a->if_name && b->if_name && streq(a->if_name, b->if_name) &&
+               a->pass == b->pass &&
                a->src_ip->ip_equals(a->src_ip, b->src_ip) &&
                chunk_equals(a->dst_net, b->dst_net) && a->prefixlen == b->prefixlen)
        {
@@ -544,7 +549,7 @@ struct private_kernel_netlink_net_t {
 static status_t manage_srcroute(private_kernel_netlink_net_t *this,
                                                                int nlmsg_type, int flags, chunk_t dst_net,
                                                                uint8_t prefixlen, host_t *gateway,
-                                                               host_t *src_ip, char *if_name);
+                                                               host_t *src_ip, char *if_name, bool pass);
 
 /**
  * Clear the queued network changes.
@@ -580,6 +585,10 @@ static job_requeue_t reinstall_routes(private_kernel_netlink_net_t *this)
                net_change_t *change, lookup = {
                        .if_name = route->if_name,
                };
+               if (route->pass)
+               {       /* no need to reinstall these, they don't reference interfaces */
+                       continue;
+               }
                /* check if a change for the outgoing interface is queued */
                change = this->net_changes->get(this->net_changes, &lookup);
                if (!change)
@@ -598,7 +607,7 @@ static job_requeue_t reinstall_routes(private_kernel_netlink_net_t *this)
                {
                        manage_srcroute(this, RTM_NEWROUTE, NLM_F_CREATE | NLM_F_EXCL,
                                                        route->dst_net, route->prefixlen, route->gateway,
-                                                       route->src_ip, route->if_name);
+                                                       route->src_ip, route->if_name, route->pass);
                }
        }
        enumerator->destroy(enumerator);
@@ -2632,7 +2641,7 @@ METHOD(kernel_net_t, del_ip, status_t,
 static status_t manage_srcroute(private_kernel_netlink_net_t *this,
                                                                int nlmsg_type, int flags, chunk_t dst_net,
                                                                uint8_t prefixlen, host_t *gateway,
-                                                               host_t *src_ip, char *if_name)
+                                                               host_t *src_ip, char *if_name, bool pass)
 {
        netlink_buf_t request;
        struct nlmsghdr *hdr;
@@ -2653,12 +2662,12 @@ static status_t manage_srcroute(private_kernel_netlink_net_t *this,
                half_net = chunk_alloca(dst_net.len);
                memset(half_net.ptr, 0, half_net.len);
                half_prefixlen = 1;
-
+               /* no throw routes in the main table */
                status = manage_srcroute(this, nlmsg_type, flags, half_net,
-                                                                half_prefixlen, gateway, src_ip, if_name);
+                                                       half_prefixlen, gateway, src_ip, if_name, FALSE);
                half_net.ptr[0] |= 0x80;
                status |= manage_srcroute(this, nlmsg_type, flags, half_net,
-                                                                 half_prefixlen, gateway, src_ip, if_name);
+                                                       half_prefixlen, gateway, src_ip, if_name, FALSE);
                return status;
        }
 
@@ -2670,10 +2679,10 @@ static status_t manage_srcroute(private_kernel_netlink_net_t *this,
        hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
 
        msg = NLMSG_DATA(hdr);
-       msg->rtm_family = src_ip->get_family(src_ip);
+       msg->rtm_family = (dst_net.len == 4) ? AF_INET : AF_INET6;
        msg->rtm_dst_len = prefixlen;
        msg->rtm_protocol = RTPROT_STATIC;
-       msg->rtm_type = RTN_UNICAST;
+       msg->rtm_type = pass ? RTN_THROW : RTN_UNICAST;
        msg->rtm_scope = RT_SCOPE_UNIVERSE;
 
        if (this->routing_table < 256)
@@ -2691,42 +2700,48 @@ static status_t manage_srcroute(private_kernel_netlink_net_t *this,
 #endif /* HAVE_RTA_TABLE */
        }
        netlink_add_attribute(hdr, RTA_DST, dst_net, sizeof(request));
-       chunk = src_ip->get_address(src_ip);
-       netlink_add_attribute(hdr, RTA_PREFSRC, chunk, sizeof(request));
-       if (gateway && gateway->get_family(gateway) == src_ip->get_family(src_ip))
-       {
-               chunk = gateway->get_address(gateway);
-               netlink_add_attribute(hdr, RTA_GATEWAY, chunk, sizeof(request));
-       }
-       ifindex = get_interface_index(this, if_name);
-       chunk.ptr = (char*)&ifindex;
-       chunk.len = sizeof(ifindex);
-       netlink_add_attribute(hdr, RTA_OIF, chunk, sizeof(request));
 
-       if (this->mtu || this->mss)
+       /* only when installing regular routes do we need all the parameters,
+        * deletes are done by destination net (except if metrics are used, which
+        * we don't support), for throw routes we don't need any of them either */
+       if (nlmsg_type == RTM_NEWROUTE && !pass)
        {
-               chunk = chunk_alloca(RTA_LENGTH((sizeof(struct rtattr) +
-                                                                                sizeof(uint32_t)) * 2));
-               chunk.len = 0;
-               rta = (struct rtattr*)chunk.ptr;
-               if (this->mtu)
+               chunk = src_ip->get_address(src_ip);
+               netlink_add_attribute(hdr, RTA_PREFSRC, chunk, sizeof(request));
+               if (gateway && gateway->get_family(gateway) == src_ip->get_family(src_ip))
                {
-                       rta->rta_type = RTAX_MTU;
-                       rta->rta_len = RTA_LENGTH(sizeof(uint32_t));
-                       memcpy(RTA_DATA(rta), &this->mtu, sizeof(uint32_t));
-                       chunk.len = rta->rta_len;
+                       chunk = gateway->get_address(gateway);
+                       netlink_add_attribute(hdr, RTA_GATEWAY, chunk, sizeof(request));
                }
-               if (this->mss)
+               ifindex = get_interface_index(this, if_name);
+               chunk.ptr = (char*)&ifindex;
+               chunk.len = sizeof(ifindex);
+               netlink_add_attribute(hdr, RTA_OIF, chunk, sizeof(request));
+
+               if (this->mtu || this->mss)
                {
-                       rta = (struct rtattr*)(chunk.ptr + RTA_ALIGN(chunk.len));
-                       rta->rta_type = RTAX_ADVMSS;
-                       rta->rta_len = RTA_LENGTH(sizeof(uint32_t));
-                       memcpy(RTA_DATA(rta), &this->mss, sizeof(uint32_t));
-                       chunk.len = RTA_ALIGN(chunk.len) + rta->rta_len;
+                       chunk = chunk_alloca(RTA_LENGTH((sizeof(struct rtattr) +
+                                                                                        sizeof(uint32_t)) * 2));
+                       chunk.len = 0;
+                       rta = (struct rtattr*)chunk.ptr;
+                       if (this->mtu)
+                       {
+                               rta->rta_type = RTAX_MTU;
+                               rta->rta_len = RTA_LENGTH(sizeof(uint32_t));
+                               memcpy(RTA_DATA(rta), &this->mtu, sizeof(uint32_t));
+                               chunk.len = rta->rta_len;
+                       }
+                       if (this->mss)
+                       {
+                               rta = (struct rtattr*)(chunk.ptr + RTA_ALIGN(chunk.len));
+                               rta->rta_type = RTAX_ADVMSS;
+                               rta->rta_len = RTA_LENGTH(sizeof(uint32_t));
+                               memcpy(RTA_DATA(rta), &this->mss, sizeof(uint32_t));
+                               chunk.len = RTA_ALIGN(chunk.len) + rta->rta_len;
+                       }
+                       netlink_add_attribute(hdr, RTA_METRICS, chunk, sizeof(request));
                }
-               netlink_add_attribute(hdr, RTA_METRICS, chunk, sizeof(request));
        }
-
        return this->socket->send_ack(this->socket, hdr);
 }
 
@@ -2769,7 +2784,7 @@ static bool route_with_dst(route_entry_lookup_t *a, route_entry_t *b)
 
 METHOD(kernel_net_t, add_route, status_t,
        private_kernel_netlink_net_t *this, chunk_t dst_net, uint8_t prefixlen,
-       host_t *gateway, host_t *src_ip, char *if_name)
+       host_t *gateway, host_t *src_ip, char *if_name, bool pass)
 {
        status_t status;
        route_entry_t *found;
@@ -2780,10 +2795,16 @@ METHOD(kernel_net_t, add_route, status_t,
                        .gateway = gateway,
                        .src_ip = src_ip,
                        .if_name = if_name,
+                       .pass = pass,
                },
                .this = this,
        };
 
+       if (!this->routing_table)
+       {       /* treat these as regular routes if installing in the main table */
+               pass = lookup.route.pass = FALSE;
+       }
+
        this->routes_lock->lock(this->routes_lock);
        found = this->routes->get(this->routes, &lookup.route);
        if (found)
@@ -2808,7 +2829,8 @@ METHOD(kernel_net_t, add_route, status_t,
        else
        {
                status = manage_srcroute(this, RTM_NEWROUTE, NLM_F_CREATE|NLM_F_REPLACE,
-                                                                dst_net, prefixlen, gateway, src_ip, if_name);
+                                                                dst_net, prefixlen, gateway, src_ip, if_name,
+                                                                pass);
        }
        if (status == SUCCESS)
        {
@@ -2821,7 +2843,7 @@ METHOD(kernel_net_t, add_route, status_t,
 
 METHOD(kernel_net_t, del_route, status_t,
        private_kernel_netlink_net_t *this, chunk_t dst_net, uint8_t prefixlen,
-       host_t *gateway, host_t *src_ip, char *if_name)
+       host_t *gateway, host_t *src_ip, char *if_name, bool pass)
 {
        status_t status;
        route_entry_t *found;
@@ -2832,10 +2854,16 @@ METHOD(kernel_net_t, del_route, status_t,
                        .gateway = gateway,
                        .src_ip = src_ip,
                        .if_name = if_name,
+                       .pass = pass,
                },
                .this = this,
        };
 
+       if (!this->routing_table)
+       {       /* treat these as regular routes if installing in the main table */
+               pass = lookup.route.pass = FALSE;
+       }
+
        this->routes_lock->lock(this->routes_lock);
        found = this->routes->remove(this->routes, &lookup.route);
        if (!found)
@@ -2860,12 +2888,12 @@ METHOD(kernel_net_t, del_route, status_t,
        {
                status = manage_srcroute(this, RTM_NEWROUTE, NLM_F_CREATE|NLM_F_REPLACE,
                                                        found->dst_net, found->prefixlen, found->gateway,
-                                                       found->src_ip, found->if_name);
+                                                       found->src_ip, found->if_name, found->pass);
        }
        else
        {
                status = manage_srcroute(this, RTM_DELROUTE, 0, dst_net, prefixlen,
-                                                                gateway, src_ip, if_name);
+                                                                gateway, src_ip, if_name, pass);
        }
        this->routes_lock->unlock(this->routes_lock);
        return status;
@@ -3111,7 +3139,8 @@ METHOD(kernel_net_t, destroy, void,
        while (enumerator->enumerate(enumerator, NULL, (void**)&route))
        {
                manage_srcroute(this, RTM_DELROUTE, 0, route->dst_net, route->prefixlen,
-                                               route->gateway, route->src_ip, route->if_name);
+                                               route->gateway, route->src_ip, route->if_name,
+                                               route->pass);
                route_entry_destroy(route);
        }
        enumerator->destroy(enumerator);
index a97daf4..3bd24d4 100644 (file)
@@ -2332,7 +2332,7 @@ static void add_exclude_route(private_kernel_pfkey_ipsec_t *this,
                                charon->kernel->add_route(charon->kernel,
                                                                        dst->get_address(dst),
                                                                        dst->get_family(dst) == AF_INET ? 32 : 128,
-                                                                       gtw, src, if_name) == SUCCESS)
+                                                                       gtw, src, if_name, FALSE) == SUCCESS)
                        {
                                INIT(exclude,
                                        .dst = dst->clone(dst),
@@ -2399,7 +2399,7 @@ static void remove_exclude_route(private_kernel_pfkey_ipsec_t *this,
                                                                        dst->get_address(dst),
                                                                        dst->get_family(dst) == AF_INET ? 32 : 128,
                                                                        route->exclude->gtw, route->exclude->src,
-                                                                       if_name) != SUCCESS)
+                                                                       if_name, FALSE) != SUCCESS)
                        {
                                DBG1(DBG_KNL, "uninstalling exclude route for %H failed", dst);
                        }
@@ -2479,8 +2479,8 @@ static bool install_route(private_kernel_pfkey_ipsec_t *this,
                }
                /* uninstall previously installed route */
                if (charon->kernel->del_route(charon->kernel, old->dst_net,
-                                                                         old->prefixlen, old->gateway,
-                                                                         old->src_ip, old->if_name) != SUCCESS)
+                                                               old->prefixlen, old->gateway,
+                                                               old->src_ip, old->if_name, FALSE) != SUCCESS)
                {
                        DBG1(DBG_KNL, "error uninstalling route installed with policy "
                                 "%R === %R %N", out->src_ts, out->dst_ts,
@@ -2512,7 +2512,7 @@ static bool install_route(private_kernel_pfkey_ipsec_t *this,
 
        switch (charon->kernel->add_route(charon->kernel, route->dst_net,
                                                                          route->prefixlen, route->gateway,
-                                                                         route->src_ip, route->if_name))
+                                                                         route->src_ip, route->if_name, FALSE))
        {
                case ALREADY_DONE:
                        /* route exists, do not uninstall */
@@ -3067,8 +3067,8 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
        {
                route_entry_t *route = policy->route;
                if (charon->kernel->del_route(charon->kernel, route->dst_net,
-                                                                         route->prefixlen, route->gateway,
-                                                                         route->src_ip, route->if_name) != SUCCESS)
+                                                       route->prefixlen, route->gateway,
+                                                       route->src_ip, route->if_name, FALSE) != SUCCESS)
                {
                        DBG1(DBG_KNL, "error uninstalling route installed with "
                                 "policy %R === %R %N", id->src_ts, id->dst_ts,
index 0bbdb1b..d28a6aa 100644 (file)
@@ -1494,7 +1494,7 @@ static status_t manage_route(private_kernel_pfroute_net_t *this, int op,
 
 METHOD(kernel_net_t, add_route, status_t,
        private_kernel_pfroute_net_t *this, chunk_t dst_net, uint8_t prefixlen,
-       host_t *gateway, host_t *src_ip, char *if_name)
+       host_t *gateway, host_t *src_ip, char *if_name, bool pass)
 {
        status_t status;
        route_entry_t *found, route = {
@@ -1523,7 +1523,7 @@ METHOD(kernel_net_t, add_route, status_t,
 
 METHOD(kernel_net_t, del_route, status_t,
        private_kernel_pfroute_net_t *this, chunk_t dst_net, uint8_t prefixlen,
-       host_t *gateway, host_t *src_ip, char *if_name)
+       host_t *gateway, host_t *src_ip, char *if_name, bool pass)
 {
        status_t status;
        route_entry_t *found, route = {
index db684b0..19d4f3e 100644 (file)
@@ -1402,7 +1402,8 @@ static bool uninstall_route(private_kernel_wfp_ipsec_t *this,
                        if (charon->kernel->get_interface(charon->kernel, src, &name))
                        {
                                res = charon->kernel->del_route(charon->kernel,
-                                               dst->get_address(dst), mask, gtw, src, name) == SUCCESS;
+                                                                               dst->get_address(dst), mask, gtw, src,
+                                                                               name, FALSE) == SUCCESS;
                                free(name);
                        }
                        route = this->routes->remove(this->routes, route);
@@ -1446,8 +1447,8 @@ static bool install_route(private_kernel_wfp_ipsec_t *this,
        {
                if (charon->kernel->get_interface(charon->kernel, src, &name))
                {
-                       if (charon->kernel->add_route(charon->kernel,
-                                               dst->get_address(dst), mask, gtw, src, name) == SUCCESS)
+                       if (charon->kernel->add_route(charon->kernel, dst->get_address(dst),
+                                                                               mask, gtw, src, name, FALSE) == SUCCESS)
                        {
                                INIT(route,
                                        .dst = dst->clone(dst),