[APR-5834]rekey child SA instead of IKE SA for IP address change
authorDenis Vinogradov <denis.vinogradov@samsung.com>
Mon, 19 Oct 2020 08:04:47 +0000 (17:04 +0900)
committerrobot <robot@samsung.com>
Wed, 4 Nov 2020 04:56:25 +0000 (13:56 +0900)
  [JIRA]: NEUS7920-26632
  [Problem]: MO call failed after WiFi AP to AP handover
  [Issue]: Child SA not re-installed on new IP address
because rekeying IKE SA does not update addresses
to childs.
  [Solution]: Rekey CHILD SA instead of IKE SA rekeying

Change-Id: I6f4a38b8e06ae9c6fdd87805a3ed274296afaac1
Signed-off-by: Denis Vinogradov <denis.vinogradov@samsung.com>
src/libcharon/sa/ike_sa.c

index 6eca87484dc659216d9d540c13d7f0cc4f4d76ac..2a4749ef164302ff48b2725c16816c36e25519f3 100755 (executable)
@@ -3126,6 +3126,36 @@ static bool is_any_path_valid(private_ike_sa_t *this)
        return valid;
 }
 
+#ifdef VOWIFI_CFG
+static status_t rekey_childs(private_ike_sa_t *this)
+{
+       enumerator_t *enumerator;
+       child_sa_t *child_sa;
+       linked_list_t *vips;
+
+       vips = linked_list_create_from_enumerator(array_create_enumerator(this->my_vips));
+
+       enumerator = array_create_enumerator(this->child_sas);
+       while (enumerator->enumerate(enumerator, &child_sa))
+       {
+               charon->child_sa_manager->remove(charon->child_sa_manager, child_sa);
+               charon->child_sa_manager->add(charon->child_sa_manager, child_sa, &this->public);
+
+               /* update policies */
+               child_sa->update(child_sa, this->my_host, this->other_host,
+                                       vips, has_condition(this, COND_NAT_ANY));
+
+               /* rekey */
+               rekey_child_sa(this, child_sa->get_protocol(child_sa),
+                                       child_sa->get_spi(child_sa, TRUE));
+       }
+       enumerator->destroy(enumerator);
+
+       vips->destroy(vips);
+       return SUCCESS;
+}
+#endif
+
 METHOD(ike_sa_t, roam, status_t,
        private_ike_sa_t *this, bool address)
 {
@@ -3223,19 +3253,24 @@ METHOD(ike_sa_t, roam, status_t,
                set_condition(this, COND_STALE, TRUE);
                return SUCCESS;
        }
-       /* since our previous path is not valid anymore, try and find a new one */
-       resolve_hosts(this);
-
 #ifdef VOWIFI_CFG
+       if (this->local_host && !this->my_host->ip_equals(this->my_host, this->local_host))
+       {
+               host_t *host = this->local_host->clone(this->local_host);
+               host->set_port(host, this->my_host->get_port(this->my_host));
+               set_my_host(this, host);
+       }
        if (this->peer_cfg)
        {
                if (this->peer_cfg->is_rekey_preferred(this->peer_cfg))
                {
-                       DBG1(DBG_IKE, "rekeying IKE_SA due to address change");
-                       return rekey(this);
+                       DBG1(DBG_IKE, "rekey CHILD_SA due to address change");
+                       return rekey_childs(this);
                }
        }
 #endif
+       /* since our previous path is not valid anymore, try and find a new one */
+       resolve_hosts(this);
 
        DBG1(DBG_IKE, "reauthenticating IKE_SA due to address change");
        return reauth(this);