]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
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 3a312048a8ef3f28e3d24b5d14d5b4e5304616eb..cc6072244a1ce69fd31a7093a1529c58ef79ebef 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 ced026dfc3a121eb60292e2cf6f41f4de9088b14..300796f8e310a5c972863cba745db88e73c41cc5 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 141198ac3d6fefdb733a7694d354450427cc7e57..50c1cac5350eb75f3c27da72d5fc363c6b04db4d 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 12475b1230e4f798be20fa1bd7a605180b4ae141..11e197013ab24b565dd720b3a528b58851f3c0f6 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 18a87b707a1bd75168934db5d41093a74aa2746b..6b5d8249a26d006daa9b261f61fc5fa0f22f6708 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 3665d455760aa04bc286be1f5bf327e02d1cc908..4c2933a03adb445d0f086a898c1861aa68e97625 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 327854ff420a3d146b1e1dad7efd97c8c55c6222..9a91549cf187c5b5150d76e4f19a80343434f967 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 f95ee3ce5951815b446b8b6ca9c61e43b3fd8162..24d93cc2f2917f0241adfe0c0b3193470f5394c1 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 a97daf4a997eb394a28c3a889f1ef5e0fa4e89a0..3bd24d43e5d1a04eee10a7aeb92ba50d81e54a9b 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 0bbdb1bc3d2f422ec77f255bc2641c51520f0811..d28a6aa1fadcd39a980d916b90c109bbee1310e4 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 db684b0600c3549c9b929cddf806c5f7b89c065a..19d4f3ef4c9ed22e7808c2ade87520528d23e2a5 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),