From 190d8cbe1931ec57484d9bb451824a7fc57979bd Mon Sep 17 00:00:00 2001 From: Boi Sletterink Date: Thu, 29 Jun 2023 17:39:37 +0200 Subject: [PATCH] libipsec: Also install routes without preferred source to forward traffic Fixes a problem installing policies with source traffic selectors that do not contain/match any of the local addresses. When installing a route for a source TS that does contain one or more local addresses, a preferred source address should be set in the route (analogous to the `src` option in `ip route add`). This address is used when the host itself sends traffic via that route (in contrast to forwarding it). When the source TS does not encompass any of the local addresses, the host is not allowed to send traffic via this route and does not need to set the preferred source address. However, the code would just return a failure because it could not find a matching local address. This commit changes this so routes without preferred source IP are installed to allow non-local traffic to get forwarded via TUN device. Closes strongswan/strongswan#1766 --- .../kernel_libipsec/kernel_libipsec_ipsec.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c index 22e1200dd9..cf35592fd8 100644 --- a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c +++ b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c @@ -419,8 +419,10 @@ static bool install_route(private_kernel_libipsec_ipsec_t *this, { traffic_selector_t *multicast, *broadcast = NULL; bool ignore = FALSE; + int family; - this->mutex->unlock(this->mutex); + /* ignore multi- and broadcast TS, othewise, install a route without + * preferred source IP to forward non-local traffic via TUN device */ switch (src_ts->get_type(src_ts)) { case TS_IPV4_ADDR_RANGE: @@ -428,24 +430,27 @@ static bool install_route(private_kernel_libipsec_ipsec_t *this, 0, 0, 0xffff); broadcast = traffic_selector_create_from_cidr("255.255.255.255/32", 0, 0, 0xffff); + family = AF_INET; break; case TS_IPV6_ADDR_RANGE: multicast = traffic_selector_create_from_cidr("ff00::/8", 0, 0, 0xffff); + family = AF_INET6; break; default: + this->mutex->unlock(this->mutex); return FALSE; } ignore = src_ts->is_contained_in(src_ts, multicast); ignore |= broadcast && src_ts->is_contained_in(src_ts, broadcast); multicast->destroy(multicast); DESTROY_IF(broadcast); - if (!ignore) + if (ignore) { - DBG1(DBG_KNL, "error installing route with policy %R === %R %N", - src_ts, dst_ts, policy_dir_names, policy->direction); + this->mutex->unlock(this->mutex); + return TRUE; } - return ignore; + src_ip = host_create_any(family); } INIT(route, -- 2.47.2