aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c5
-rw-r--r--src/charon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c4
-rw-r--r--src/charon/processing/jobs/migrate_job.c30
-rw-r--r--src/charon/processing/jobs/migrate_job.h1
-rw-r--r--src/charon/sa/child_sa.c71
5 files changed, 75 insertions, 36 deletions
diff --git a/src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c
index 3714582e4..c395aac1f 100644
--- a/src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c
+++ b/src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c
@@ -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;
- 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))
{
@@ -618,7 +617,7 @@ static void process_migrate(private_kernel_netlink_ipsec_t *this, struct nlmsghd
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);
diff --git a/src/charon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c b/src/charon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
index 2b2fb7f0a..237176925 100644
--- a/src/charon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
+++ b/src/charon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
@@ -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,
- 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)
@@ -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);
}
- 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);
diff --git a/src/charon/processing/jobs/migrate_job.c b/src/charon/processing/jobs/migrate_job.c
index f9b1df26b..92bdac04f 100644
--- a/src/charon/processing/jobs/migrate_job.c
+++ b/src/charon/processing/jobs/migrate_job.c
@@ -85,8 +85,38 @@ static void execute(private_migrate_job_t *this)
}
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);
+
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
diff --git a/src/charon/processing/jobs/migrate_job.h b/src/charon/processing/jobs/migrate_job.h
index ecd2d6fe5..09e6ba097 100644
--- a/src/charon/processing/jobs/migrate_job.h
+++ b/src/charon/processing/jobs/migrate_job.h
@@ -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 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
diff --git a/src/charon/sa/child_sa.c b/src/charon/sa/child_sa.c
index f1cca18db..82670b057 100644
--- a/src/charon/sa/child_sa.c
+++ b/src/charon/sa/child_sa.c
@@ -673,21 +673,45 @@ static status_t update_hosts(private_child_sa_t *this,
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))
@@ -754,25 +778,10 @@ static status_t update_hosts(private_child_sa_t *this,
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;
-
set_state(this, old);
-
+
return SUCCESS;
}