ike-sa: uninstall CHILD_SAs before removing virtual IPs
authorMartin Willi <martin@revosec.ch>
Thu, 18 Jul 2013 08:31:52 +0000 (10:31 +0200)
committerMartin Willi <martin@revosec.ch>
Thu, 18 Jul 2013 08:35:38 +0000 (10:35 +0200)
a3854d83 changed cleanup order. But we should remove CHILD_SAs first, as routes
for CHILD_SAs might get deleted while removing virtual IPs, resulting in
an error when a CHILD_SA tries to uninstall its route.

src/libcharon/sa/ike_sa.c

index aa04d15..5086120 100644 (file)
@@ -2123,6 +2123,7 @@ METHOD(ike_sa_t, destroy, void,
        private_ike_sa_t *this)
 {
        attribute_entry_t entry;
+       child_sa_t *child_sa;
        host_t *vip;
 
        charon->bus->set_sa(charon->bus, &this->public);
@@ -2137,6 +2138,12 @@ METHOD(ike_sa_t, destroy, void,
                                                                   this->other_id, entry.type, entry.data);
                free(entry.data.ptr);
        }
+       /* uninstall CHILD_SAs before virtual IPs, otherwise we might kill
+        * routes that the CHILD_SA tries to uninstall. */
+       while (array_remove(this->child_sas, ARRAY_TAIL, &child_sa))
+       {
+               child_sa->destroy(child_sa);
+       }
        while (array_remove(this->my_vips, ARRAY_TAIL, &vip))
        {
                hydra->kernel_interface->del_ip(hydra->kernel_interface, vip, -1, TRUE);
@@ -2165,7 +2172,7 @@ METHOD(ike_sa_t, destroy, void,
        /* unset SA after here to avoid usage by the listeners */
        charon->bus->set_sa(charon->bus, NULL);
 
-       array_destroy_offset(this->child_sas, offsetof(child_sa_t, destroy));
+       array_destroy(this->child_sas);
        DESTROY_IF(this->keymat);
        array_destroy(this->attributes);
        array_destroy(this->my_vips);