mirror of
https://github.com/strongswan/strongswan.git
synced 2025-10-04 00:00:14 -04:00
kernel-pfkey: Only install exclude route if not routing via outbound interface
When installing routes based on remote traffic selectors, it can be necessary to install an exclude route for the remote peer to avoid a routing loop and continue to be able to reach it via IKE/ESP. However, such routes are only necessary, if the routes we install don't go via outbound interface. That's the case when using VIPs and routing via TUN devices, or when using internal source IPs and routing via their interfaces. Installing such exclude routes if not necessary can cause issues on FreeBSD (EINVAL when sending packets to the peer).
This commit is contained in:
parent
012e4cd902
commit
5de6ab82a6
@ -2429,6 +2429,7 @@ static bool install_route(private_kernel_pfkey_ipsec_t *this,
|
||||
{
|
||||
route_entry_t *route, *old;
|
||||
host_t *host, *src, *dst;
|
||||
char *out_interface = NULL;
|
||||
bool is_virtual;
|
||||
|
||||
if (charon->kernel->get_address_by_ts(charon->kernel, out->src_ts, &host,
|
||||
@ -2456,7 +2457,7 @@ static bool install_route(private_kernel_pfkey_ipsec_t *this,
|
||||
* this is required for example on Linux. */
|
||||
if (is_virtual || this->route_via_internal)
|
||||
{
|
||||
free(route->if_name);
|
||||
out_interface = route->if_name;
|
||||
route->if_name = NULL;
|
||||
src = route->src_ip;
|
||||
}
|
||||
@ -2476,6 +2477,7 @@ static bool install_route(private_kernel_pfkey_ipsec_t *this,
|
||||
!charon->kernel->get_interface(charon->kernel, src, &route->if_name))
|
||||
{
|
||||
route_entry_destroy(route);
|
||||
free(out_interface);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -2486,6 +2488,7 @@ static bool install_route(private_kernel_pfkey_ipsec_t *this,
|
||||
if (route_entry_equals(old, route))
|
||||
{ /* such a route already exists */
|
||||
route_entry_destroy(route);
|
||||
free(out_interface);
|
||||
return TRUE;
|
||||
}
|
||||
/* uninstall previously installed route */
|
||||
@ -2501,8 +2504,10 @@ static bool install_route(private_kernel_pfkey_ipsec_t *this,
|
||||
policy->route = NULL;
|
||||
}
|
||||
|
||||
/* if remote traffic selector covers the IKE peer, add an exclude route */
|
||||
if (charon->kernel->get_features(charon->kernel) & KERNEL_REQUIRE_EXCLUDE_ROUTE)
|
||||
/* if we don't route via outbound interface and the remote traffic selector
|
||||
* covers the IKE peer, add an exclude route */
|
||||
if (!streq(route->if_name, out_interface) &&
|
||||
charon->kernel->get_features(charon->kernel) & KERNEL_REQUIRE_EXCLUDE_ROUTE)
|
||||
{
|
||||
if (out->dst_ts->is_host(out->dst_ts, dst))
|
||||
{
|
||||
@ -2510,6 +2515,7 @@ static bool install_route(private_kernel_pfkey_ipsec_t *this,
|
||||
"with IKE traffic", out->src_ts, out->dst_ts, policy_dir_names,
|
||||
policy->direction);
|
||||
route_entry_destroy(route);
|
||||
free(out_interface);
|
||||
return FALSE;
|
||||
}
|
||||
if (out->dst_ts->includes(out->dst_ts, dst))
|
||||
@ -2517,6 +2523,7 @@ static bool install_route(private_kernel_pfkey_ipsec_t *this,
|
||||
add_exclude_route(this, route, out->generic.sa->src, dst);
|
||||
}
|
||||
}
|
||||
free(out_interface);
|
||||
|
||||
DBG2(DBG_KNL, "installing route: %R via %H src %H dev %s",
|
||||
out->dst_ts, route->gateway, route->src_ip, route->if_name);
|
||||
|
Loading…
x
Reference in New Issue
Block a user