diff options
author | Martin Willi <martin@strongswan.org> | 2007-05-16 08:32:15 +0000 |
---|---|---|
committer | Martin Willi <martin@strongswan.org> | 2007-05-16 08:32:15 +0000 |
commit | ce27ac8012b5b8f4a0c3afedf7569906cbb40d89 (patch) | |
tree | a7c665ab1862c8176d2efd30b21965f93f24243f /src/charon/control | |
parent | 933521270db7644dbcaaf7f389b1d512e5102728 (diff) | |
download | strongswan-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.c | 126 | ||||
-rwxr-xr-x | src/charon/control/interfaces/stroke_interface.c | 68 |
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); |