From f836d433a9f8a641d1064fd4fe8f19b49675bfe1 Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Wed, 20 Feb 2013 08:57:17 +0100 Subject: [PATCH 1/2] When detecting a duplicate IKEv1 SA, adopt children, as it might be a rekeying --- src/libcharon/sa/ike_sa_manager.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/libcharon/sa/ike_sa_manager.c b/src/libcharon/sa/ike_sa_manager.c index 2ac8c3123..a195ff9f2 100644 --- a/src/libcharon/sa/ike_sa_manager.c +++ b/src/libcharon/sa/ike_sa_manager.c @@ -1745,6 +1745,23 @@ METHOD(ike_sa_manager_t, create_id_enumerator, enumerator_t*, (void*)id_enumerator_cleanup, ids); } +/** + * Move all CHILD_SAs from old to new + */ +static void adopt_children(ike_sa_t *old, ike_sa_t *new) +{ + enumerator_t *enumerator; + child_sa_t *child_sa; + + enumerator = old->create_child_sa_enumerator(old); + while (enumerator->enumerate(enumerator, &child_sa)) + { + old->remove_child_sa(old, enumerator); + new->add_child_sa(new, child_sa); + } + enumerator->destroy(enumerator); +} + METHOD(ike_sa_manager_t, check_uniqueness, bool, private_ike_sa_manager_t *this, ike_sa_t *ike_sa, bool force_replace) { @@ -1796,6 +1813,10 @@ METHOD(ike_sa_manager_t, check_uniqueness, bool, { case UNIQUE_REPLACE: charon->bus->alert(charon->bus, ALERT_UNIQUE_REPLACE); + if (duplicate->get_version(duplicate) == IKEV1) + { + adopt_children(duplicate, ike_sa); + } DBG1(DBG_IKE, "deleting duplicate IKE_SA for peer " "'%Y' due to uniqueness policy", other); status = duplicate->delete(duplicate); From 3dc9d427c92ee3bece4bc1c3c575250156deeebc Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Wed, 20 Feb 2013 09:16:00 +0100 Subject: [PATCH 2/2] After IKEv1 reauthentication, reinstall VIP routes after migrating CHILD_SAs During IKEv1 reauthentication, the virtual IP gets removed, then reinstalled. The CHILD_SAs get migrated, but any associated route gets removed from the kernel. Reinstall routes after adding the virtual IP again. --- src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c | 4 ++++ 1 file changed, 4 insertions(+) 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; } }