aboutsummaryrefslogtreecommitdiffstats
path: root/src/charon/control
diff options
context:
space:
mode:
authorMartin Willi <martin@strongswan.org>2007-05-16 08:32:15 +0000
committerMartin Willi <martin@strongswan.org>2007-05-16 08:32:15 +0000
commitce27ac8012b5b8f4a0c3afedf7569906cbb40d89 (patch)
treea7c665ab1862c8176d2efd30b21965f93f24243f /src/charon/control
parent933521270db7644dbcaaf7f389b1d512e5102728 (diff)
downloadstrongswan-ce27ac8012b5b8f4a0c3afedf7569906cbb40d89.tar.bz2
strongswan-ce27ac8012b5b8f4a0c3afedf7569906cbb40d89.tar.xz
routing/unrouting through interface
Diffstat (limited to 'src/charon/control')
-rw-r--r--src/charon/control/interface_manager.c126
-rwxr-xr-xsrc/charon/control/interfaces/stroke_interface.c68
2 files changed, 181 insertions, 13 deletions
diff --git a/src/charon/control/interface_manager.c b/src/charon/control/interface_manager.c
index 79f412ef7..8d9bdb6ee 100644
--- a/src/charon/control/interface_manager.c
+++ b/src/charon/control/interface_manager.c
@@ -183,6 +183,62 @@ static bool terminate_child_listener(interface_bus_listener_t *this, signal_t si
}
/**
+ * 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.
*/
static status_t initiate(private_interface_manager_t *this,
@@ -377,6 +433,7 @@ static status_t terminate_child(interface_manager_t *this, u_int32_t reqid,
if (child_sa == NULL)
{
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
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,
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,
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;
}
/**
diff --git a/src/charon/control/interfaces/stroke_interface.c b/src/charon/control/interfaces/stroke_interface.c
index 96dcc7651..bbfc6506b 100755
--- a/src/charon/control/interfaces/stroke_interface.c
+++ b/src/charon/control/interfaces/stroke_interface.c
@@ -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,
- stroke_msg_t *msg, FILE *out, bool route)
+ stroke_msg_t *msg, FILE *out)
{
- route_job_t *job;
peer_cfg_t *peer_cfg;
child_cfg_t *child_cfg;
+ stroke_log_info_t info;
pop_string(msg, &(msg->route.name));
- DBG1(DBG_CFG, "received stroke: %s '%s'",
- route ? "route" : "unroute", msg->route.name);
+ DBG1(DBG_CFG, "received stroke: route '%s'", msg->route.name);
peer_cfg = get_peer_cfg_by_name(msg->route.name);
if (peer_cfg == NULL)
@@ -787,10 +786,57 @@ static void stroke_route(private_stroke_interface_t *this,
peer_cfg->destroy(peer_cfg);
return;
}
- fprintf(out, "%s policy '%s'\n",
- route ? "routing" : "unrouting", msg->route.name);
- job = route_job_create(peer_cfg, child_cfg, route);
- charon->job_queue->add(charon->job_queue, (job_t*)job);
+
+ info.out = out;
+ info.level = msg->output_verbosity;
+ 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);
break;
case STR_ROUTE:
- stroke_route(this, msg, out, TRUE);
+ stroke_route(this, msg, out);
break;
case STR_UNROUTE:
- stroke_route(this, msg, out, FALSE);
+ stroke_unroute(this, msg, out);
break;
case STR_TERMINATE:
stroke_terminate(this, msg, out);