diff --git a/src/frontends/android/app/src/main/jni/libandroidbridge/kernel/android_net.c b/src/frontends/android/app/src/main/jni/libandroidbridge/kernel/android_net.c index 3a312048a..cc6072244 100644 --- a/src/frontends/android/app/src/main/jni/libandroidbridge/kernel/android_net.c +++ b/src/frontends/android/app/src/main/jni/libandroidbridge/kernel/android_net.c @@ -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; } diff --git a/src/libcharon/kernel/kernel_interface.c b/src/libcharon/kernel/kernel_interface.c index ced026dfc..300796f8e 100644 --- a/src/libcharon/kernel/kernel_interface.c +++ b/src/libcharon/kernel/kernel_interface.c @@ -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, diff --git a/src/libcharon/kernel/kernel_interface.h b/src/libcharon/kernel/kernel_interface.h index 141198ac3..50c1cac53 100644 --- a/src/libcharon/kernel/kernel_interface.h +++ b/src/libcharon/kernel/kernel_interface.h @@ -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. diff --git a/src/libcharon/kernel/kernel_net.h b/src/libcharon/kernel/kernel_net.h index 12475b123..11e197013 100644 --- a/src/libcharon/kernel/kernel_net.h +++ b/src/libcharon/kernel/kernel_net.h @@ -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. diff --git a/src/libcharon/plugins/kernel_iph/kernel_iph_net.c b/src/libcharon/plugins/kernel_iph/kernel_iph_net.c index 18a87b707..6b5d8249a 100644 --- a/src/libcharon/plugins/kernel_iph/kernel_iph_net.c +++ b/src/libcharon/plugins/kernel_iph/kernel_iph_net.c @@ -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); } diff --git a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c index 3665d4557..4c2933a03 100644 --- a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c +++ b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c @@ -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); diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c index 327854ff4..9a91549cf 100644 --- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c +++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c @@ -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, diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c index f95ee3ce5..24d93cc2f 100644 --- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c +++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c @@ -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) - { - 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)); - } + 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) + { + 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)); + } + } 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); diff --git a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c index a97daf4a9..3bd24d43e 100644 --- a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c +++ b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c @@ -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, diff --git a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c b/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c index 0bbdb1bc3..d28a6aa1f 100644 --- a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c +++ b/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c @@ -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 = { diff --git a/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c b/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c index db684b060..19d4f3ef4 100644 --- a/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c +++ b/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c @@ -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),