{
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,
* 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;
}
!charon->kernel->get_interface(charon->kernel, src, &route->if_name))
{
route_entry_destroy(route);
+ free(out_interface);
return FALSE;
}
if (route_entry_equals(old, route))
{ /* such a route already exists */
route_entry_destroy(route);
+ free(out_interface);
return TRUE;
}
/* uninstall previously installed route */
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))
{
"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))
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);