completed migration of MIPv6 connections
authorAndreas Steffen <andreas.steffen@strongswan.org>
Sun, 16 Nov 2008 21:19:58 +0000 (21:19 -0000)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Sun, 16 Nov 2008 21:19:58 +0000 (21:19 -0000)
src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c
src/charon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
src/charon/processing/jobs/migrate_job.c
src/charon/processing/jobs/migrate_job.h
src/charon/sa/child_sa.c

index 3714582..c395aac 100644 (file)
@@ -580,8 +580,7 @@ static void process_migrate(private_kernel_netlink_ipsec_t *this, struct nlmsghd
        dst_ts = selector2ts(&policy_id->sel, FALSE);
        dir = (policy_dir_t)policy_id->dir;
 
        dst_ts = selector2ts(&policy_id->sel, FALSE);
        dir = (policy_dir_t)policy_id->dir;
 
-       DBG2(DBG_KNL, "  policy: %R === %R %N, index %u", src_ts, dst_ts,
-                                  policy_dir_names, dir, policy_id->index);
+       DBG2(DBG_KNL, "  policy: %R === %R %N", src_ts, dst_ts, policy_dir_names);
 
        while (RTA_OK(rta, rtasize))
        {
 
        while (RTA_OK(rta, rtasize))
        {
@@ -618,7 +617,7 @@ static void process_migrate(private_kernel_netlink_ipsec_t *this, struct nlmsghd
                rta = RTA_NEXT(rta, rtasize);
        }
 
                rta = RTA_NEXT(rta, rtasize);
        }
 
-       if (src_ts && dst_ts)
+       if (src_ts && dst_ts && local && remote)
        {
                DBG1(DBG_KNL, "creating migrate job for policy %R === %R %N with reqid {%u}",
                                           src_ts, dst_ts, policy_dir_names, dir, reqid, local);
        {
                DBG1(DBG_KNL, "creating migrate job for policy %R === %R %N with reqid {%u}",
                                           src_ts, dst_ts, policy_dir_names, dir, reqid, local);
index 2b2fb7f..2371769 100644 (file)
@@ -858,7 +858,7 @@ static void process_migrate(private_kernel_pfkey_ipsec_t *this, struct sadb_msg*
        dst_ts = sadb_address2ts(response.dst);
        dir = kernel2dir(response.x_policy->sadb_x_policy_dir);
        DBG2(DBG_KNL, "  policy %R === %R %N, id %u", src_ts, dst_ts,
        dst_ts = sadb_address2ts(response.dst);
        dir = kernel2dir(response.x_policy->sadb_x_policy_dir);
        DBG2(DBG_KNL, "  policy %R === %R %N, id %u", src_ts, dst_ts,
-                                        policy_dir_names, dir, response.x_policy->sadb_x_policy_id);
+                                        policy_dir_names, dir);
        
        /* SADB_X_EXT_KMADDRESS is not present in unpatched kernels < 2.6.28 */   
        if (response.x_kmaddress)
        
        /* SADB_X_EXT_KMADDRESS is not present in unpatched kernels < 2.6.28 */   
        if (response.x_kmaddress)
@@ -875,7 +875,7 @@ static void process_migrate(private_kernel_pfkey_ipsec_t *this, struct sadb_msg*
                DBG2(DBG_KNL, "  kmaddress: %H...%H", local, remote);
        }
        
                DBG2(DBG_KNL, "  kmaddress: %H...%H", local, remote);
        }
        
-       if (src_ts && dst_ts)
+       if (src_ts && dst_ts && local && remote)
        {
                DBG1(DBG_KNL, "creating migrate job for policy %R === %R %N with reqid {%u}",
                                           src_ts, dst_ts, policy_dir_names, dir, reqid, local);
        {
                DBG1(DBG_KNL, "creating migrate job for policy %R === %R %N with reqid {%u}",
                                           src_ts, dst_ts, policy_dir_names, dir, reqid, local);
index f9b1df2..92bdac0 100644 (file)
@@ -85,8 +85,38 @@ static void execute(private_migrate_job_t *this)
        }
        if (ike_sa)
        {
        }
        if (ike_sa)
        {
+               iterator_t *children;
+               child_sa_t *child_sa;
+               host_t *host;
+
+               children = ike_sa->create_child_sa_iterator(ike_sa);
+               while (children->iterate(children, (void**)&child_sa))
+               {
+                       if (child_sa->get_reqid(child_sa) == this->reqid)
+                       {
+                               break;
+                       }
+               }
+               children->destroy(children);
                DBG2(DBG_JOB, "found CHILD_SA with reqid {%d}", this->reqid);
                DBG2(DBG_JOB, "found CHILD_SA with reqid {%d}", this->reqid);
+
                ike_sa->set_kmaddress(ike_sa, this->local, this->remote);
                ike_sa->set_kmaddress(ike_sa, this->local, this->remote);
+
+               host = this->local->clone(this->local);
+               host->set_port(host, IKEV2_UDP_PORT);
+               ike_sa->set_my_host(ike_sa, host);
+
+               host = this->remote->clone(this->remote);
+               host->set_port(host, IKEV2_UDP_PORT);
+               ike_sa->set_other_host(ike_sa, host);
+
+               if (child_sa->update_hosts(child_sa, this->local, this->remote,
+                               ike_sa->get_virtual_ip(ike_sa, TRUE),
+                               ike_sa->has_condition(ike_sa, COND_NAT_ANY)) == NOT_SUPPORTED)
+               {
+                       ike_sa->rekey_child_sa(ike_sa, child_sa->get_protocol(child_sa),
+                                                                  child_sa->get_spi(child_sa, TRUE));
+               }
                charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
        }
        else
                charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
        }
        else
index ecd2d6f..09e6ba0 100644 (file)
@@ -51,6 +51,7 @@ struct migrate_job_t {
  * @param reqid                reqid of the CHILD_SA to acquire
  * @param src_ts       source traffic selector to be used in the policy
  * @param dst_ts       destination traffic selector to be used in the policy
  * @param reqid                reqid of the CHILD_SA to acquire
  * @param src_ts       source traffic selector to be used in the policy
  * @param dst_ts       destination traffic selector to be used in the policy
+ * @param dir       direction of the policy (in|out)
  * @param local     local host address to be used in the IKE_SA
  * @param remote    remote host address to be used in the IKE_SA
  * @return                     migrate_job_t object
  * @param local     local host address to be used in the IKE_SA
  * @param remote    remote host address to be used in the IKE_SA
  * @return                     migrate_job_t object
index f1cca18..82670b0 100644 (file)
@@ -673,21 +673,45 @@ static status_t update_hosts(private_child_sa_t *this,
        old = this->state;
        set_state(this, CHILD_UPDATING);
        
        old = this->state;
        set_state(this, CHILD_UPDATING);
        
-       /* update our (initator) SA */
-       if (charon->kernel_interface->update_sa(charon->kernel_interface, this->my_spi,
-                       this->protocol, this->ipcomp != IPCOMP_NONE ? this->my_cpi : 0,
-                       this->other_addr, this->my_addr, other, me,
-                       this->encap, encap) == NOT_SUPPORTED)
-       {
-               return NOT_SUPPORTED;
-       }
-       /* update his (responder) SA */
-       if (charon->kernel_interface->update_sa(charon->kernel_interface, this->other_spi, 
-                       this->protocol, this->ipcomp != IPCOMP_NONE ? this->other_cpi : 0,
-                       this->my_addr, this->other_addr, me, other,
-                       this->encap, encap) == NOT_SUPPORTED)
+       if (!this->config->use_proxy_mode(this->config) || this->mode != MODE_TRANSPORT)
        {
        {
-               return NOT_SUPPORTED;
+               /* update our (initator) SA */
+               if (this->my_spi)
+               {
+                       if (charon->kernel_interface->update_sa(charon->kernel_interface,
+                                                       this->my_spi, this->protocol,
+                                                       this->ipcomp != IPCOMP_NONE ? this->my_cpi : 0,
+                                                       this->other_addr, this->my_addr, other, me,
+                                                       this->encap, encap) == NOT_SUPPORTED)
+                       {
+                               return NOT_SUPPORTED;
+                       }
+               }
+               
+               /* update his (responder) SA */
+               if (this->other_spi)
+               {
+                       if (charon->kernel_interface->update_sa(charon->kernel_interface,
+                                                       this->other_spi, this->protocol,
+                                                       this->ipcomp != IPCOMP_NONE ? this->other_cpi : 0,
+                                                       this->my_addr, this->other_addr, me, other,
+                                                       this->encap, encap) == NOT_SUPPORTED)
+                       {
+                               return NOT_SUPPORTED;
+                       }
+               }
+
+               /* apply hosts */
+               if (!me->equals(me, this->my_addr))
+               {
+                       this->my_addr->destroy(this->my_addr);
+                       this->my_addr = me->clone(me);
+               }
+               if (!other->equals(other, this->other_addr))
+               {
+                       this->other_addr->destroy(this->other_addr);
+                       this->other_addr = other->clone(other);
+               }
        }
        
        if (this->config->install_policy(this->config))
        }
        
        if (this->config->install_policy(this->config))
@@ -754,25 +778,10 @@ static status_t update_hosts(private_child_sa_t *this,
                        enumerator->destroy(enumerator);
                }
        }
                        enumerator->destroy(enumerator);
                }
        }
-       
-       /* apply hosts */
-       if (!this->config->use_proxy_mode(this->config) || this->mode != MODE_TRANSPORT)
-       {
-               if (!me->equals(me, this->my_addr))
-               {
-                       this->my_addr->destroy(this->my_addr);
-                       this->my_addr = me->clone(me);
-               }
-               if (!other->equals(other, this->other_addr))
-               {
-                       this->other_addr->destroy(this->other_addr);
-                       this->other_addr = other->clone(other);
-               }
-       }
+
        this->encap = encap;
        this->encap = encap;
-       
        set_state(this, old);
        set_state(this, old);
-       
+
        return SUCCESS;
 }
 
        return SUCCESS;
 }