diff options
Diffstat (limited to 'src/libhydra/plugins/kernel_netlink')
-rw-r--r-- | src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c | 27 | ||||
-rw-r--r-- | src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c | 4 |
2 files changed, 25 insertions, 6 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..e81e55c24 100644 --- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c +++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c @@ -787,7 +787,7 @@ static traffic_selector_t* selector2ts(struct xfrm_selector *sel, bool src) if (host) { return traffic_selector_create_from_subnet(host, prefixlen, - sel->proto, port); + sel->proto, port, port ?: 65535); } return NULL; } @@ -1036,6 +1036,12 @@ static job_requeue_t receive_events(private_kernel_netlink_ipsec_t *this) return JOB_REQUEUE_DIRECT; } +METHOD(kernel_ipsec_t, get_features, kernel_feature_t, + private_kernel_netlink_ipsec_t *this) +{ + return KERNEL_ESP_V3_TFC; +} + /** * Get an SPI for a specific protocol from the kernel. */ @@ -2196,14 +2202,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 +2226,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); @@ -2734,6 +2749,7 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create() INIT(this, .public = { .interface = { + .get_features = _get_features, .get_spi = _get_spi, .get_cpi = _get_cpi, .add_sa = _add_sa, @@ -2822,4 +2838,3 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create() return &this->public; } - diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c index e47887859..b6df9879c 100644 --- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c +++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c @@ -1757,6 +1757,10 @@ METHOD(kernel_net_t, add_ip, status_t, DBG2(DBG_KNL, "virtual IP %H installed on %s", virtual_ip, entry->iface->ifname); this->lock->unlock(this->lock); + /* during IKEv1 reauthentication, children get moved from + * old the new SA before the virtual IP is available. This + * kills the route for our virtual IP, reinstall. */ + queue_route_reinstall(this, entry->iface->ifname); return SUCCESS; } } |