aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libcharon/plugins/ha/ha_dispatcher.c11
-rw-r--r--src/libcharon/sa/ike_sa.c18
-rw-r--r--src/libcharon/sa/ike_sa.h7
-rw-r--r--src/libcharon/sa/ikev1/tasks/mode_config.c4
-rw-r--r--src/libcharon/sa/ikev2/tasks/ike_config.c4
5 files changed, 43 insertions, 1 deletions
diff --git a/src/libcharon/plugins/ha/ha_dispatcher.c b/src/libcharon/plugins/ha/ha_dispatcher.c
index f07b4ea21..97ed13111 100644
--- a/src/libcharon/plugins/ha/ha_dispatcher.c
+++ b/src/libcharon/plugins/ha/ha_dispatcher.c
@@ -310,7 +310,7 @@ static void process_ike_update(private_ha_dispatcher_t *this,
ike_sa_t *ike_sa = NULL;
peer_cfg_t *peer_cfg = NULL;
auth_cfg_t *auth;
- bool received_vip = FALSE, first_peer_addr = TRUE;
+ bool received_vip = FALSE, first_local_vip = TRUE, first_peer_addr = TRUE;
enumerator = message->create_attribute_enumerator(message);
while (enumerator->enumerate(enumerator, &attribute, &value))
@@ -344,9 +344,18 @@ static void process_ike_update(private_ha_dispatcher_t *this,
ike_sa->set_other_host(ike_sa, value.host->clone(value.host));
break;
case HA_LOCAL_VIP:
+ if (first_local_vip)
+ {
+ ike_sa->clear_virtual_ips(ike_sa, TRUE);
+ first_local_vip = FALSE;
+ }
ike_sa->add_virtual_ip(ike_sa, TRUE, value.host);
break;
case HA_REMOTE_VIP:
+ if (!received_vip)
+ {
+ ike_sa->clear_virtual_ips(ike_sa, FALSE);
+ }
ike_sa->add_virtual_ip(ike_sa, FALSE, value.host);
received_vip = TRUE;
break;
diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c
index 7672accc4..e3744b6c0 100644
--- a/src/libcharon/sa/ike_sa.c
+++ b/src/libcharon/sa/ike_sa.c
@@ -757,6 +757,23 @@ METHOD(ike_sa_t, add_virtual_ip, void,
}
}
+
+METHOD(ike_sa_t, clear_virtual_ips, void,
+ private_ike_sa_t *this, bool local)
+{
+ linked_list_t *vips = local ? this->my_vips : this->other_vips;
+ host_t *vip;
+
+ while (vips->remove_first(vips, (void**)&vip) == SUCCESS)
+ {
+ if (local)
+ {
+ hydra->kernel_interface->del_ip(hydra->kernel_interface, vip);
+ }
+ vip->destroy(vip);
+ }
+}
+
METHOD(ike_sa_t, create_virtual_ip_enumerator, enumerator_t*,
private_ike_sa_t *this, bool local)
{
@@ -2193,6 +2210,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator,
.reset = _reset,
.get_unique_id = _get_unique_id,
.add_virtual_ip = _add_virtual_ip,
+ .clear_virtual_ips = _clear_virtual_ips,
.create_virtual_ip_enumerator = _create_virtual_ip_enumerator,
.add_configuration_attribute = _add_configuration_attribute,
.set_kmaddress = _set_kmaddress,
diff --git a/src/libcharon/sa/ike_sa.h b/src/libcharon/sa/ike_sa.h
index d2a394b6c..d9ee6b876 100644
--- a/src/libcharon/sa/ike_sa.h
+++ b/src/libcharon/sa/ike_sa.h
@@ -942,6 +942,13 @@ struct ike_sa_t {
void (*add_virtual_ip) (ike_sa_t *this, bool local, host_t *ip);
/**
+ * Clear all virtual IPs stored on this IKE_SA.
+ *
+ * @param local TRUE to clear local addresses, FALSE for remote
+ */
+ void (*clear_virtual_ips) (ike_sa_t *this, bool local);
+
+ /**
* Create an enumerator over virtual IPs.
*
* @param local TRUE to get local virtual IP, FALSE for remote
diff --git a/src/libcharon/sa/ikev1/tasks/mode_config.c b/src/libcharon/sa/ikev1/tasks/mode_config.c
index 03072a2a7..a134ad562 100644
--- a/src/libcharon/sa/ikev1/tasks/mode_config.c
+++ b/src/libcharon/sa/ikev1/tasks/mode_config.c
@@ -332,6 +332,8 @@ METHOD(task_t, build_r, status_t,
vips = linked_list_create();
pools = linked_list_create();
+ this->ike_sa->clear_virtual_ips(this->ike_sa, FALSE);
+
enumerator = this->vips->create_enumerator(this->vips);
while (enumerator->enumerate(enumerator, &requested))
{
@@ -411,6 +413,8 @@ METHOD(task_t, process_i, status_t,
process_payloads(this, message);
+ this->ike_sa->clear_virtual_ips(this->ike_sa, TRUE);
+
enumerator = this->vips->create_enumerator(this->vips);
while (enumerator->enumerate(enumerator, &host))
{
diff --git a/src/libcharon/sa/ikev2/tasks/ike_config.c b/src/libcharon/sa/ikev2/tasks/ike_config.c
index e788bb5f9..fbfcb0ea9 100644
--- a/src/libcharon/sa/ikev2/tasks/ike_config.c
+++ b/src/libcharon/sa/ikev2/tasks/ike_config.c
@@ -344,6 +344,8 @@ METHOD(task_t, build_r, status_t,
vips = linked_list_create();
pools = linked_list_create();
+ this->ike_sa->clear_virtual_ips(this->ike_sa, FALSE);
+
enumerator = this->vips->create_enumerator(this->vips);
while (enumerator->enumerate(enumerator, &requested))
{
@@ -437,6 +439,8 @@ METHOD(task_t, process_i, status_t,
process_payloads(this, message);
+ this->ike_sa->clear_virtual_ips(this->ike_sa, TRUE);
+
enumerator = this->vips->create_enumerator(this->vips);
while (enumerator->enumerate(enumerator, &host))
{