routing/unrouting through interface
This commit is contained in:
@@ -182,6 +182,62 @@ static bool terminate_child_listener(interface_bus_listener_t *this, signal_t si
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* listener function for route
|
||||||
|
*/
|
||||||
|
static bool route_listener(interface_bus_listener_t *this, signal_t signal,
|
||||||
|
level_t level, int thread, ike_sa_t *ike_sa,
|
||||||
|
char* format, va_list args)
|
||||||
|
{
|
||||||
|
if (this->ike_sa == ike_sa)
|
||||||
|
{
|
||||||
|
if (!this->callback(this->param, signal, level, ike_sa, format, args))
|
||||||
|
{
|
||||||
|
this->cancelled = TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
switch (signal)
|
||||||
|
{
|
||||||
|
case CHILD_ROUTE_SUCCESS:
|
||||||
|
case CHILD_ROUTE_FAILED:
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* listener function for unroute
|
||||||
|
*/
|
||||||
|
static bool unroute_listener(interface_bus_listener_t *this, signal_t signal,
|
||||||
|
level_t level, int thread, ike_sa_t *ike_sa,
|
||||||
|
char* format, va_list args)
|
||||||
|
{
|
||||||
|
if (this->ike_sa == ike_sa)
|
||||||
|
{
|
||||||
|
if (!this->callback(this->param, signal, level, ike_sa, format, args))
|
||||||
|
{
|
||||||
|
this->cancelled = TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
switch (signal)
|
||||||
|
{
|
||||||
|
case CHILD_UNROUTE_SUCCESS:
|
||||||
|
case CHILD_UNROUTE_FAILED:
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of interface_manager_t.initiate.
|
* Implementation of interface_manager_t.initiate.
|
||||||
*/
|
*/
|
||||||
@@ -377,6 +433,7 @@ static status_t terminate_child(interface_manager_t *this, u_int32_t reqid,
|
|||||||
|
|
||||||
if (child_sa == NULL)
|
if (child_sa == NULL)
|
||||||
{
|
{
|
||||||
|
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
|
||||||
return NOT_FOUND;
|
return NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -453,7 +510,40 @@ static status_t route(interface_manager_t *this,
|
|||||||
peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
|
peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
|
||||||
interface_manager_cb_t callback, void *param)
|
interface_manager_cb_t callback, void *param)
|
||||||
{
|
{
|
||||||
return FAILED;
|
ike_sa_t *ike_sa;
|
||||||
|
ike_cfg_t *ike_cfg;
|
||||||
|
status_t status = SUCCESS;
|
||||||
|
|
||||||
|
ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
|
||||||
|
|
||||||
|
ike_sa = charon->ike_sa_manager->checkout_by_peer(charon->ike_sa_manager,
|
||||||
|
ike_cfg->get_my_host(ike_cfg), ike_cfg->get_other_host(ike_cfg),
|
||||||
|
peer_cfg->get_my_id(peer_cfg), peer_cfg->get_other_id(peer_cfg));
|
||||||
|
|
||||||
|
if (ike_sa->get_peer_cfg(ike_sa) == NULL)
|
||||||
|
{
|
||||||
|
ike_sa->set_peer_cfg(ike_sa, peer_cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we listen passively only, as routing is done by one thread only */
|
||||||
|
if (callback)
|
||||||
|
{
|
||||||
|
interface_bus_listener_t listener;
|
||||||
|
|
||||||
|
listener.listener.signal = (void*)route_listener;
|
||||||
|
listener.callback = callback;
|
||||||
|
listener.ike_sa = ike_sa;
|
||||||
|
listener.param = param;
|
||||||
|
listener.cancelled = FALSE;
|
||||||
|
charon->bus->add_listener(charon->bus, &listener.listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ike_sa->route(ike_sa, child_cfg) != SUCCESS)
|
||||||
|
{
|
||||||
|
status = FAILED;
|
||||||
|
}
|
||||||
|
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -462,7 +552,39 @@ static status_t route(interface_manager_t *this,
|
|||||||
static status_t unroute(interface_manager_t *this, u_int32_t reqid,
|
static status_t unroute(interface_manager_t *this, u_int32_t reqid,
|
||||||
interface_manager_cb_t callback, void *param)
|
interface_manager_cb_t callback, void *param)
|
||||||
{
|
{
|
||||||
return FAILED;
|
ike_sa_t *ike_sa;
|
||||||
|
status_t status;
|
||||||
|
|
||||||
|
ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
|
||||||
|
reqid, TRUE);
|
||||||
|
if (ike_sa == NULL)
|
||||||
|
{
|
||||||
|
return NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we listen passively only, as routing is done by one thread only */
|
||||||
|
if (callback)
|
||||||
|
{
|
||||||
|
interface_bus_listener_t listener;
|
||||||
|
|
||||||
|
listener.listener.signal = (void*)unroute_listener;
|
||||||
|
listener.callback = callback;
|
||||||
|
listener.ike_sa = ike_sa;
|
||||||
|
listener.param = param;
|
||||||
|
listener.cancelled = FALSE;
|
||||||
|
charon->bus->add_listener(charon->bus, &listener.listener);
|
||||||
|
}
|
||||||
|
status = ike_sa->unroute(ike_sa, reqid);
|
||||||
|
if (status == DESTROY_ME)
|
||||||
|
{
|
||||||
|
charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
|
||||||
|
status = SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -755,18 +755,17 @@ static void stroke_initiate(private_stroke_interface_t *this,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* route/unroute a policy (install SPD entries)
|
* route a policy (install SPD entries)
|
||||||
*/
|
*/
|
||||||
static void stroke_route(private_stroke_interface_t *this,
|
static void stroke_route(private_stroke_interface_t *this,
|
||||||
stroke_msg_t *msg, FILE *out, bool route)
|
stroke_msg_t *msg, FILE *out)
|
||||||
{
|
{
|
||||||
route_job_t *job;
|
|
||||||
peer_cfg_t *peer_cfg;
|
peer_cfg_t *peer_cfg;
|
||||||
child_cfg_t *child_cfg;
|
child_cfg_t *child_cfg;
|
||||||
|
stroke_log_info_t info;
|
||||||
|
|
||||||
pop_string(msg, &(msg->route.name));
|
pop_string(msg, &(msg->route.name));
|
||||||
DBG1(DBG_CFG, "received stroke: %s '%s'",
|
DBG1(DBG_CFG, "received stroke: route '%s'", msg->route.name);
|
||||||
route ? "route" : "unroute", msg->route.name);
|
|
||||||
|
|
||||||
peer_cfg = get_peer_cfg_by_name(msg->route.name);
|
peer_cfg = get_peer_cfg_by_name(msg->route.name);
|
||||||
if (peer_cfg == NULL)
|
if (peer_cfg == NULL)
|
||||||
@@ -787,10 +786,57 @@ static void stroke_route(private_stroke_interface_t *this,
|
|||||||
peer_cfg->destroy(peer_cfg);
|
peer_cfg->destroy(peer_cfg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fprintf(out, "%s policy '%s'\n",
|
|
||||||
route ? "routing" : "unrouting", msg->route.name);
|
info.out = out;
|
||||||
job = route_job_create(peer_cfg, child_cfg, route);
|
info.level = msg->output_verbosity;
|
||||||
charon->job_queue->add(charon->job_queue, (job_t*)job);
|
charon->interfaces->route(charon->interfaces, peer_cfg, child_cfg,
|
||||||
|
(interface_manager_cb_t)stroke_log, &info);
|
||||||
|
peer_cfg->destroy(peer_cfg);
|
||||||
|
child_cfg->destroy(child_cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* unroute a policy
|
||||||
|
*/
|
||||||
|
static void stroke_unroute(private_stroke_interface_t *this,
|
||||||
|
stroke_msg_t *msg, FILE *out)
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
ike_sa_t *ike_sa;
|
||||||
|
iterator_t *iterator;
|
||||||
|
stroke_log_info_t info;
|
||||||
|
|
||||||
|
pop_string(msg, &(msg->terminate.name));
|
||||||
|
name = msg->terminate.name;
|
||||||
|
|
||||||
|
info.out = out;
|
||||||
|
info.level = msg->output_verbosity;
|
||||||
|
|
||||||
|
iterator = charon->interfaces->create_ike_sa_iterator(charon->interfaces);
|
||||||
|
while (iterator->iterate(iterator, (void**)&ike_sa))
|
||||||
|
{
|
||||||
|
child_sa_t *child_sa;
|
||||||
|
iterator_t *children;
|
||||||
|
u_int32_t id;
|
||||||
|
|
||||||
|
children = ike_sa->create_child_sa_iterator(ike_sa);
|
||||||
|
while (children->iterate(children, (void**)&child_sa))
|
||||||
|
{
|
||||||
|
if (child_sa->get_state(child_sa) == CHILD_ROUTED &&
|
||||||
|
streq(name, child_sa->get_name(child_sa)))
|
||||||
|
{
|
||||||
|
id = child_sa->get_reqid(child_sa);
|
||||||
|
children->destroy(children);
|
||||||
|
iterator->destroy(iterator);
|
||||||
|
charon->interfaces->unroute(charon->interfaces, id,
|
||||||
|
(interface_manager_cb_t)stroke_log, &info);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
children->destroy(children);
|
||||||
|
}
|
||||||
|
iterator->destroy(iterator);
|
||||||
|
DBG1(DBG_CFG, "no such SA found");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1479,10 +1525,10 @@ static void stroke_process(private_stroke_interface_t *this, int strokefd)
|
|||||||
stroke_initiate(this, msg, out);
|
stroke_initiate(this, msg, out);
|
||||||
break;
|
break;
|
||||||
case STR_ROUTE:
|
case STR_ROUTE:
|
||||||
stroke_route(this, msg, out, TRUE);
|
stroke_route(this, msg, out);
|
||||||
break;
|
break;
|
||||||
case STR_UNROUTE:
|
case STR_UNROUTE:
|
||||||
stroke_route(this, msg, out, FALSE);
|
stroke_unroute(this, msg, out);
|
||||||
break;
|
break;
|
||||||
case STR_TERMINATE:
|
case STR_TERMINATE:
|
||||||
stroke_terminate(this, msg, out);
|
stroke_terminate(this, msg, out);
|
||||||
|
|||||||
@@ -935,7 +935,7 @@ static status_t route(private_ike_sa_t *this, child_cfg_t *child_cfg)
|
|||||||
/**
|
/**
|
||||||
* Implementation of ike_sa_t.unroute.
|
* Implementation of ike_sa_t.unroute.
|
||||||
*/
|
*/
|
||||||
static status_t unroute(private_ike_sa_t *this, child_cfg_t *child_cfg)
|
static status_t unroute(private_ike_sa_t *this, u_int32_t reqid)
|
||||||
{
|
{
|
||||||
iterator_t *iterator;
|
iterator_t *iterator;
|
||||||
child_sa_t *child_sa;
|
child_sa_t *child_sa;
|
||||||
@@ -948,7 +948,7 @@ static status_t unroute(private_ike_sa_t *this, child_cfg_t *child_cfg)
|
|||||||
while (iterator->iterate(iterator, (void**)&child_sa))
|
while (iterator->iterate(iterator, (void**)&child_sa))
|
||||||
{
|
{
|
||||||
if (child_sa->get_state(child_sa) == CHILD_ROUTED &&
|
if (child_sa->get_state(child_sa) == CHILD_ROUTED &&
|
||||||
streq(child_sa->get_name(child_sa), child_cfg->get_name(child_cfg)))
|
child_sa->get_reqid(child_sa) == reqid)
|
||||||
{
|
{
|
||||||
iterator->remove(iterator);
|
iterator->remove(iterator);
|
||||||
SIG(CHILD_UNROUTE_SUCCESS, "CHILD_SA unrouted");
|
SIG(CHILD_UNROUTE_SUCCESS, "CHILD_SA unrouted");
|
||||||
@@ -1873,7 +1873,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
|
|||||||
this->public.process_message = (status_t(*)(ike_sa_t*, message_t*)) process_message;
|
this->public.process_message = (status_t(*)(ike_sa_t*, message_t*)) process_message;
|
||||||
this->public.initiate = (status_t(*)(ike_sa_t*,child_cfg_t*)) initiate;
|
this->public.initiate = (status_t(*)(ike_sa_t*,child_cfg_t*)) initiate;
|
||||||
this->public.route = (status_t(*)(ike_sa_t*,child_cfg_t*)) route;
|
this->public.route = (status_t(*)(ike_sa_t*,child_cfg_t*)) route;
|
||||||
this->public.unroute = (status_t(*)(ike_sa_t*,child_cfg_t*)) unroute;
|
this->public.unroute = (status_t(*)(ike_sa_t*,u_int32_t)) unroute;
|
||||||
this->public.acquire = (status_t(*)(ike_sa_t*,u_int32_t)) acquire;
|
this->public.acquire = (status_t(*)(ike_sa_t*,u_int32_t)) acquire;
|
||||||
this->public.get_ike_cfg = (ike_cfg_t*(*)(ike_sa_t*))get_ike_cfg;
|
this->public.get_ike_cfg = (ike_cfg_t*(*)(ike_sa_t*))get_ike_cfg;
|
||||||
this->public.set_ike_cfg = (void(*)(ike_sa_t*,ike_cfg_t*))set_ike_cfg;
|
this->public.set_ike_cfg = (void(*)(ike_sa_t*,ike_cfg_t*))set_ike_cfg;
|
||||||
|
|||||||
@@ -333,12 +333,13 @@ struct ike_sa_t {
|
|||||||
* @brief Unroute a policy in the kernel previously routed.
|
* @brief Unroute a policy in the kernel previously routed.
|
||||||
*
|
*
|
||||||
* @param this calling object
|
* @param this calling object
|
||||||
* @param child_cfg child config to unroute
|
* @param reqid reqid of CHILD_SA to unroute
|
||||||
* @return
|
* @return
|
||||||
* - SUCCESS if route removed
|
* - SUCCESS if route removed
|
||||||
|
* - NOT_FOUND if CHILD_SA not found
|
||||||
* - DESTROY_ME if last CHILD_SA was unrouted
|
* - DESTROY_ME if last CHILD_SA was unrouted
|
||||||
*/
|
*/
|
||||||
status_t (*unroute) (ike_sa_t *this, child_cfg_t *child_cfg);
|
status_t (*unroute) (ike_sa_t *this, u_int32_t reqid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Acquire connection setup for an installed kernel policy.
|
* @brief Acquire connection setup for an installed kernel policy.
|
||||||
|
|||||||
Reference in New Issue
Block a user