migrate_job() finds a matching child_cfg
This commit is contained in:
@@ -52,6 +52,7 @@ processing/jobs/acquire_job.c processing/jobs/acquire_job.h \
|
||||
processing/jobs/callback_job.c processing/jobs/callback_job.h \
|
||||
processing/jobs/delete_child_sa_job.c processing/jobs/delete_child_sa_job.h \
|
||||
processing/jobs/delete_ike_sa_job.c processing/jobs/delete_ike_sa_job.h \
|
||||
processing/jobs/migrate_job.c processing/jobs/migrate_job.h \
|
||||
processing/jobs/process_message_job.c processing/jobs/process_message_job.h \
|
||||
processing/jobs/rekey_child_sa_job.c processing/jobs/rekey_child_sa_job.h \
|
||||
processing/jobs/rekey_ike_sa_job.c processing/jobs/rekey_ike_sa_job.h \
|
||||
|
||||
@@ -336,6 +336,31 @@ static linked_list_t* get_traffic_selectors(private_child_cfg_t *this, bool loca
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of child_cfg_t.equal_traffic_selectors.
|
||||
*/
|
||||
bool equal_traffic_selectors(private_child_cfg_t *this, bool local, traffic_selector_t *ts)
|
||||
{
|
||||
linked_list_t *list;
|
||||
enumerator_t *enumerator;
|
||||
traffic_selector_t *other_ts;
|
||||
bool result;
|
||||
|
||||
list = (local) ? this->my_ts : this->other_ts;
|
||||
|
||||
if (list->get_count(list) != 1)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
enumerator = list->create_enumerator(list);
|
||||
enumerator->enumerate(enumerator, &other_ts);
|
||||
|
||||
result = ts->equals(ts, other_ts);
|
||||
|
||||
enumerator->destroy(enumerator);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of child_cfg_t.get_updown.
|
||||
*/
|
||||
@@ -462,6 +487,7 @@ child_cfg_t *child_cfg_create(char *name, u_int32_t lifetime,
|
||||
this->public.get_name = (char* (*) (child_cfg_t*))get_name;
|
||||
this->public.add_traffic_selector = (void (*)(child_cfg_t*,bool,traffic_selector_t*))add_traffic_selector;
|
||||
this->public.get_traffic_selectors = (linked_list_t*(*)(child_cfg_t*,bool,linked_list_t*,host_t*))get_traffic_selectors;
|
||||
this->public.equal_traffic_selectors = (bool (*)(child_cfg_t*,bool,traffic_selector_t*))equal_traffic_selectors;
|
||||
this->public.add_proposal = (void (*) (child_cfg_t*,proposal_t*))add_proposal;
|
||||
this->public.get_proposals = (linked_list_t* (*) (child_cfg_t*,bool))get_proposals;
|
||||
this->public.select_proposal = (proposal_t* (*) (child_cfg_t*,linked_list_t*,bool))select_proposal;
|
||||
|
||||
@@ -153,6 +153,16 @@ struct child_cfg_t {
|
||||
linked_list_t *supplied,
|
||||
host_t *host);
|
||||
|
||||
/**
|
||||
* Checks the [single] traffic selectors for equality
|
||||
*
|
||||
* @param local TRUE for TS on local side, FALSE for remote
|
||||
* @param ts single traffic selector to compare with
|
||||
* @return TRUE if TS are equal, FALSE otherwise
|
||||
*/
|
||||
bool (*equal_traffic_selectors)(child_cfg_t *this, bool local,
|
||||
traffic_selector_t *ts);
|
||||
|
||||
/**
|
||||
* Get the updown script to run for the CHILD_SA.
|
||||
*
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <utils/linked_list.h>
|
||||
#include <processing/jobs/callback_job.h>
|
||||
#include <processing/jobs/acquire_job.h>
|
||||
#include <processing/jobs/migrate_job.h>
|
||||
#include <processing/jobs/rekey_child_sa_job.h>
|
||||
#include <processing/jobs/delete_child_sa_job.h>
|
||||
#include <processing/jobs/update_sa_job.h>
|
||||
@@ -501,7 +502,7 @@ static void process_acquire(private_kernel_netlink_ipsec_t *this, struct nlmsghd
|
||||
}
|
||||
src_ts = selector2ts(&acquire->sel, TRUE);
|
||||
dst_ts = selector2ts(&acquire->sel, FALSE);
|
||||
DBG1(DBG_KNL, "creating acquire job %R === %R for CHILD_SA with reqid {%d}",
|
||||
DBG1(DBG_KNL, "creating acquire job for policy %R === %R with reqid {%u}",
|
||||
src_ts, dst_ts, reqid);
|
||||
job = (job_t*)acquire_job_create(reqid, src_ts, dst_ts);
|
||||
charon->processor->queue_job(charon->processor, job);
|
||||
@@ -526,7 +527,7 @@ static void process_expire(private_kernel_netlink_ipsec_t *this, struct nlmsghdr
|
||||
|
||||
if (protocol != PROTO_ESP && protocol != PROTO_AH)
|
||||
{
|
||||
DBG2(DBG_KNL, "ignoring XFRM_MSG_EXPIRE for SA with SPI %.8x and reqid {%d} "
|
||||
DBG2(DBG_KNL, "ignoring XFRM_MSG_EXPIRE for SA with SPI %.8x and reqid {%u} "
|
||||
"which is not a CHILD_SA", ntohl(spi), reqid);
|
||||
return;
|
||||
}
|
||||
@@ -558,6 +559,7 @@ static void process_migrate(private_kernel_netlink_ipsec_t *this, struct nlmsghd
|
||||
struct rtattr *rta;
|
||||
size_t rtasize;
|
||||
u_int32_t reqid = 0;
|
||||
policy_dir_t dir;
|
||||
job_t *job;
|
||||
|
||||
policy_id = (struct xfrm_userpolicy_id*)NLMSG_DATA(hdr);
|
||||
@@ -568,8 +570,10 @@ static void process_migrate(private_kernel_netlink_ipsec_t *this, struct nlmsghd
|
||||
|
||||
src_ts = selector2ts(&policy_id->sel, TRUE);
|
||||
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, policy_id->dir, policy_id->index);
|
||||
policy_dir_names, dir, policy_id->index);
|
||||
|
||||
while (RTA_OK(rta, rtasize))
|
||||
{
|
||||
@@ -605,9 +609,21 @@ static void process_migrate(private_kernel_netlink_ipsec_t *this, struct nlmsghd
|
||||
}
|
||||
rta = RTA_NEXT(rta, rtasize);
|
||||
}
|
||||
DESTROY_IF(src_ts);
|
||||
DESTROY_IF(dst_ts);
|
||||
DESTROY_IF(local);
|
||||
|
||||
if (src_ts && dst_ts)
|
||||
{
|
||||
DBG1(DBG_KNL, "creating migrate job for policy %R === %R %N "
|
||||
"with reqid {%u}, kmaddress = %H",
|
||||
src_ts, dst_ts, policy_dir_names, dir, reqid, local);
|
||||
job = (job_t*)migrate_job_create(reqid, src_ts, dst_ts, dir, local);
|
||||
charon->processor->queue_job(charon->processor, job);
|
||||
}
|
||||
else
|
||||
{
|
||||
DESTROY_IF(src_ts);
|
||||
DESTROY_IF(dst_ts);
|
||||
DESTROY_IF(local);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -634,7 +650,7 @@ static void process_mapping(private_kernel_netlink_ipsec_t *this,
|
||||
if (host)
|
||||
{
|
||||
DBG1(DBG_KNL, "NAT mappings of ESP CHILD_SA with SPI %.8x and "
|
||||
"reqid {%d} changed, queuing update job", ntohl(spi), reqid);
|
||||
"reqid {%u} changed, queuing update job", ntohl(spi), reqid);
|
||||
job = (job_t*)update_sa_job_create(reqid, host);
|
||||
charon->processor->queue_job(charon->processor, job);
|
||||
}
|
||||
@@ -782,16 +798,16 @@ static status_t get_spi(private_kernel_netlink_ipsec_t *this,
|
||||
protocol_id_t protocol, u_int32_t reqid,
|
||||
u_int32_t *spi)
|
||||
{
|
||||
DBG2(DBG_KNL, "getting SPI for reqid {%d}", reqid);
|
||||
DBG2(DBG_KNL, "getting SPI for reqid {%u}", reqid);
|
||||
|
||||
if (get_spi_internal(this, src, dst, proto_ike2kernel(protocol),
|
||||
0xc0000000, 0xcFFFFFFF, reqid, spi) != SUCCESS)
|
||||
{
|
||||
DBG1(DBG_KNL, "unable to get SPI for reqid {%d}", reqid);
|
||||
DBG1(DBG_KNL, "unable to get SPI for reqid {%u}", reqid);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
DBG2(DBG_KNL, "got SPI %.8x for reqid {%d}", ntohl(*spi), reqid);
|
||||
DBG2(DBG_KNL, "got SPI %.8x for reqid {%u}", ntohl(*spi), reqid);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
@@ -805,18 +821,18 @@ static status_t get_cpi(private_kernel_netlink_ipsec_t *this,
|
||||
{
|
||||
u_int32_t received_spi = 0;
|
||||
|
||||
DBG2(DBG_KNL, "getting CPI for reqid {%d}", reqid);
|
||||
DBG2(DBG_KNL, "getting CPI for reqid {%u}", reqid);
|
||||
|
||||
if (get_spi_internal(this, src, dst,
|
||||
IPPROTO_COMP, 0x100, 0xEFFF, reqid, &received_spi) != SUCCESS)
|
||||
{
|
||||
DBG1(DBG_KNL, "unable to get CPI for reqid {%d}", reqid);
|
||||
DBG1(DBG_KNL, "unable to get CPI for reqid {%u}", reqid);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
*cpi = htons((u_int16_t)ntohl(received_spi));
|
||||
|
||||
DBG2(DBG_KNL, "got CPI %.4x for reqid {%d}", ntohs(*cpi), reqid);
|
||||
DBG2(DBG_KNL, "got CPI %.4x for reqid {%u}", ntohs(*cpi), reqid);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
@@ -841,7 +857,7 @@ static status_t add_sa(private_kernel_netlink_ipsec_t *this,
|
||||
|
||||
memset(&request, 0, sizeof(request));
|
||||
|
||||
DBG2(DBG_KNL, "adding SAD entry with SPI %.8x and reqid {%d}",
|
||||
DBG2(DBG_KNL, "adding SAD entry with SPI %.8x and reqid {%u}",
|
||||
ntohl(spi), reqid);
|
||||
|
||||
hdr = (struct nlmsghdr*)request;
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <utils/host.h>
|
||||
#include <processing/jobs/callback_job.h>
|
||||
#include <processing/jobs/acquire_job.h>
|
||||
#include <processing/jobs/migrate_job.h>
|
||||
#include <processing/jobs/rekey_child_sa_job.h>
|
||||
#include <processing/jobs/delete_child_sa_job.h>
|
||||
#include <processing/jobs/update_sa_job.h>
|
||||
@@ -777,8 +778,8 @@ static void process_acquire(private_kernel_pfkey_ipsec_t *this, struct sadb_msg*
|
||||
dst_ts = sadb_address2ts(response.dst);
|
||||
pthread_mutex_unlock(&this->mutex);
|
||||
|
||||
DBG1(DBG_KNL, "creating acquire job %R === %R for CHILD_SA with reqid {%d}",
|
||||
src_ts, dst_ts, reqid);
|
||||
DBG1(DBG_KNL, "creating acquire job for policy %R === %R with reqid {%u}",
|
||||
src_ts, dst_ts, reqid);
|
||||
job = (job_t*)acquire_job_create(reqid, src_ts, dst_ts);
|
||||
charon->processor->queue_job(charon->processor, job);
|
||||
}
|
||||
@@ -809,12 +810,12 @@ static void process_expire(private_kernel_pfkey_ipsec_t *this, struct sadb_msg*
|
||||
|
||||
if (protocol != PROTO_ESP && protocol != PROTO_AH)
|
||||
{
|
||||
DBG2(DBG_KNL, "ignoring SADB_EXPIRE for SA with SPI %.8x and reqid {%d} "
|
||||
DBG2(DBG_KNL, "ignoring SADB_EXPIRE for SA with SPI %.8x and reqid {%u} "
|
||||
"which is not a CHILD_SA", ntohl(spi), reqid);
|
||||
return;
|
||||
}
|
||||
|
||||
DBG1(DBG_KNL, "creating %s job for %N CHILD_SA with SPI %.8x and reqid {%d}",
|
||||
DBG1(DBG_KNL, "creating %s job for %N CHILD_SA with SPI %.8x and reqid {%u}",
|
||||
hard ? "delete" : "rekey", protocol_id_names,
|
||||
protocol, ntohl(spi), reqid);
|
||||
if (hard)
|
||||
@@ -836,7 +837,9 @@ static void process_migrate(private_kernel_pfkey_ipsec_t *this, struct sadb_msg*
|
||||
pfkey_msg_t response;
|
||||
traffic_selector_t *src_ts, *dst_ts;
|
||||
policy_dir_t dir;
|
||||
u_int32_t reqid = 0;
|
||||
host_t *local;
|
||||
job_t *job;
|
||||
|
||||
DBG2(DBG_KNL, "received an SADB_X_MIGRATE");
|
||||
|
||||
@@ -853,9 +856,20 @@ static void process_migrate(private_kernel_pfkey_ipsec_t *this, struct sadb_msg*
|
||||
policy_dir_names, dir, response.x_policy->sadb_x_policy_id);
|
||||
DBG2(DBG_KNL, " kmaddress: %H", local);
|
||||
|
||||
src_ts->destroy(src_ts);
|
||||
dst_ts->destroy(dst_ts);
|
||||
local->destroy(local);
|
||||
if (src_ts && dst_ts)
|
||||
{
|
||||
DBG1(DBG_KNL, "creating migrate job for policy %R === %R %N "
|
||||
"with reqid {%u}, kmaddress = %H",
|
||||
src_ts, dst_ts, policy_dir_names, dir, reqid, local);
|
||||
job = (job_t*)migrate_job_create(reqid, src_ts, dst_ts, dir, local);
|
||||
charon->processor->queue_job(charon->processor, job);
|
||||
}
|
||||
else
|
||||
{
|
||||
DESTROY_IF(src_ts);
|
||||
DESTROY_IF(dst_ts);
|
||||
DESTROY_IF(local);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -907,7 +921,7 @@ static void process_mapping(private_kernel_pfkey_ipsec_t *this, struct sadb_msg*
|
||||
if (host)
|
||||
{
|
||||
DBG1(DBG_KNL, "NAT mappings of ESP CHILD_SA with SPI %.8x and "
|
||||
"reqid {%d} changed, queuing update job", ntohl(spi), reqid);
|
||||
"reqid {%u} changed, queuing update job", ntohl(spi), reqid);
|
||||
job = (job_t*)update_sa_job_create(reqid, host);
|
||||
charon->processor->queue_job(charon->processor, job);
|
||||
}
|
||||
@@ -1086,7 +1100,7 @@ static status_t add_sa(private_kernel_pfkey_ipsec_t *this,
|
||||
|
||||
memset(&request, 0, sizeof(request));
|
||||
|
||||
DBG2(DBG_KNL, "adding SAD entry with SPI %.8x and reqid {%d}", ntohl(spi), reqid);
|
||||
DBG2(DBG_KNL, "adding SAD entry with SPI %.8x and reqid {%u}", ntohl(spi), reqid);
|
||||
|
||||
msg = (struct sadb_msg*)request;
|
||||
msg->sadb_msg_version = PF_KEY_V2;
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* $Id: acquire_job.c 4535 2008-10-31 01:43:23Z andreas $
|
||||
*/
|
||||
|
||||
#include "migrate_job.h"
|
||||
|
||||
#include <daemon.h>
|
||||
|
||||
#include <config/child_cfg.h>
|
||||
|
||||
|
||||
typedef struct private_migrate_job_t private_migrate_job_t;
|
||||
|
||||
/**
|
||||
* Private data of a migrate_job_t object.
|
||||
*/
|
||||
struct private_migrate_job_t {
|
||||
/**
|
||||
* Public migrate_job_t interface.
|
||||
*/
|
||||
migrate_job_t public;
|
||||
|
||||
/**
|
||||
* reqid of the CHILD_SA if it already exists
|
||||
*/
|
||||
u_int32_t reqid;
|
||||
|
||||
/**
|
||||
* source traffic selector
|
||||
*/
|
||||
traffic_selector_t *src_ts;
|
||||
|
||||
/**
|
||||
* destination traffic selector
|
||||
*/
|
||||
traffic_selector_t *dst_ts;
|
||||
|
||||
/**
|
||||
* local host address to be used
|
||||
*/
|
||||
host_t *local;
|
||||
};
|
||||
|
||||
/**
|
||||
* Implementation of job_t.destroy.
|
||||
*/
|
||||
static void destroy(private_migrate_job_t *this)
|
||||
{
|
||||
DESTROY_IF(this->src_ts);
|
||||
DESTROY_IF(this->dst_ts);
|
||||
DESTROY_IF(this->local);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of job_t.execute.
|
||||
*/
|
||||
static void execute(private_migrate_job_t *this)
|
||||
{
|
||||
ike_sa_t *ike_sa = NULL;
|
||||
|
||||
if (this->reqid)
|
||||
{
|
||||
ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
|
||||
this->reqid, TRUE);
|
||||
}
|
||||
if (ike_sa == NULL)
|
||||
{
|
||||
enumerator_t *enumerator, *children;
|
||||
peer_cfg_t *peer_cfg;
|
||||
child_cfg_t *found_cfg = NULL;
|
||||
|
||||
enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends);
|
||||
while (enumerator->enumerate(enumerator, (void**)&peer_cfg))
|
||||
{
|
||||
ike_cfg_t *ike_cfg;
|
||||
child_cfg_t *child_cfg;
|
||||
|
||||
if (peer_cfg->get_ike_version(peer_cfg) != 2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
|
||||
children = peer_cfg->create_child_cfg_enumerator(peer_cfg);
|
||||
while (children->enumerate(children, &child_cfg))
|
||||
{
|
||||
if (child_cfg->equal_traffic_selectors(child_cfg, TRUE, this->src_ts) &&
|
||||
child_cfg->equal_traffic_selectors(child_cfg, FALSE, this->dst_ts))
|
||||
{
|
||||
found_cfg = child_cfg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
children->destroy(children);
|
||||
if (found_cfg)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
if (found_cfg)
|
||||
{
|
||||
DBG1(DBG_JOB, "found matching child_cfg '%s'",
|
||||
found_cfg->get_name(found_cfg));
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_JOB, "no matching child_cfg found");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_JOB, "migrate job found CHILD_SA with reqid {%d}", this->reqid);
|
||||
|
||||
/* set my_host to local */
|
||||
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
|
||||
}
|
||||
destroy(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
migrate_job_t *migrate_job_create(u_int32_t reqid,
|
||||
traffic_selector_t *src_ts,
|
||||
traffic_selector_t *dst_ts,
|
||||
policy_dir_t dir,
|
||||
host_t *local)
|
||||
{
|
||||
private_migrate_job_t *this = malloc_thing(private_migrate_job_t);
|
||||
|
||||
/* interface functions */
|
||||
this->public.job_interface.execute = (void (*) (job_t *)) execute;
|
||||
this->public.job_interface.destroy = (void (*)(job_t*)) destroy;
|
||||
|
||||
/* private variables */
|
||||
this->reqid = reqid;
|
||||
this->src_ts = (dir == POLICY_OUT) ? src_ts : dst_ts;
|
||||
this->dst_ts = (dir == POLICY_OUT) ? dst_ts : src_ts;
|
||||
this->local = local;
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* $Id: acquire_job.h 4535 2008-10-31 01:43:23Z andreas $
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup migrate_job migrate_job
|
||||
* @{ @ingroup jobs
|
||||
*/
|
||||
|
||||
#ifndef MIGRATE_JOB_H_
|
||||
#define MIGRATE_JOB_H_
|
||||
|
||||
typedef struct migrate_job_t migrate_job_t;
|
||||
|
||||
#include <library.h>
|
||||
#include <utils/host.h>
|
||||
#include <config/traffic_selector.h>
|
||||
#include <kernel/kernel_ipsec.h>
|
||||
#include <processing/jobs/job.h>
|
||||
|
||||
/**
|
||||
* Class representing a MIGRATE Job.
|
||||
*
|
||||
* This job sets a routed CHILD_SA for an existing IPsec policy.
|
||||
*/
|
||||
struct migrate_job_t {
|
||||
/**
|
||||
* The job_t interface.
|
||||
*/
|
||||
job_t job_interface;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a job of type MIGRATE.
|
||||
*
|
||||
* We use the reqid or the traffic selectors to find a matching CHILD_SA.
|
||||
*
|
||||
* @param reqid reqid of the CHILD_SA to acquire
|
||||
* @param src_ts source traffic selector
|
||||
* @param dst_ts destination traffic selector
|
||||
* @param local local host address to be used in the IKE_SA
|
||||
* @return migrate_job_t object
|
||||
*/
|
||||
migrate_job_t *migrate_job_create(u_int32_t reqid,
|
||||
traffic_selector_t *src_ts,
|
||||
traffic_selector_t *dst_ts,
|
||||
policy_dir_t dir,
|
||||
host_t *local);
|
||||
|
||||
#endif /* MIGRATE_JOB_H_ @} */
|
||||
Reference in New Issue
Block a user