aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Willi <martin@revosec.ch>2013-02-20 16:17:31 +0100
committerMartin Willi <martin@revosec.ch>2013-02-20 16:32:24 +0100
commita2fd08dd26eadb75c4a58506fd916a9adf6d23b3 (patch)
treed05a5be6eaebd29d06b16c6b9b643849848788b0
parent122b4b6e6d948b1b5ffac7d4e99030ae4d53a189 (diff)
downloadstrongswan-a2fd08dd26eadb75c4a58506fd916a9adf6d23b3.tar.bz2
strongswan-a2fd08dd26eadb75c4a58506fd916a9adf6d23b3.tar.xz
Install a route for shunt policies
If we install a virtual IP, its source route would render the shunt policy useless, as locally generated traffic wouldn't match. Having a route for each shunt policy with higher priority chooses the correct source address for bypassed destinations.
-rw-r--r--src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
index f9b2634a0..47df381b4 100644
--- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
+++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
@@ -2196,14 +2196,15 @@ static status_t add_policy_internal(private_kernel_netlink_ipsec_t *this,
/* install a route, if:
* - this is a forward policy (to just get one for each child)
- * - we are in tunnel/BEET mode
+ * - we are in tunnel/BEET mode or install a bypass policy
* - routing is not disabled via strongswan.conf
*/
- if (policy->direction == POLICY_FWD &&
- ipsec->cfg.mode != MODE_TRANSPORT && this->install_routes)
+ if (policy->direction == POLICY_FWD && this->install_routes &&
+ (mapping->type != POLICY_IPSEC || ipsec->cfg.mode != MODE_TRANSPORT))
{
policy_sa_fwd_t *fwd = (policy_sa_fwd_t*)mapping;
route_entry_t *route;
+ host_t *iface;
INIT(route,
.prefixlen = policy->sel.prefixlen_s,
@@ -2219,9 +2220,17 @@ static status_t add_policy_internal(private_kernel_netlink_ipsec_t *this,
route->dst_net = chunk_alloc(policy->sel.family == AF_INET ? 4 : 16);
memcpy(route->dst_net.ptr, &policy->sel.saddr, route->dst_net.len);
+ /* get the interface to install the route for. If we have a local
+ * address, use it. Otherwise (for shunt policies) use the
+ * routes source address. */
+ iface = ipsec->dst;
+ if (iface->is_anyaddr(iface))
+ {
+ iface = route->src_ip;
+ }
/* install route via outgoing interface */
if (!hydra->kernel_interface->get_interface(hydra->kernel_interface,
- ipsec->dst, &route->if_name))
+ iface, &route->if_name))
{
this->mutex->unlock(this->mutex);
route_entry_destroy(route);
@@ -2822,4 +2831,3 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create()
return &this->public;
}
-