diff --git a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c index 22e1200dd..cf35592fd 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,