diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libcharon/Makefile.am | 1 | ||||
-rw-r--r-- | src/libcharon/daemon.c | 2 | ||||
-rw-r--r-- | src/libcharon/daemon.h | 6 | ||||
-rw-r--r-- | src/libcharon/plugins/stroke/stroke_config.c | 3 | ||||
-rw-r--r-- | src/libcharon/plugins/stroke/stroke_control.c | 46 | ||||
-rw-r--r-- | src/libcharon/plugins/stroke/stroke_list.c | 37 | ||||
-rw-r--r-- | src/libcharon/processing/jobs/start_action_job.c | 12 | ||||
-rw-r--r-- | src/libcharon/sa/shunt_manager.c | 242 | ||||
-rw-r--r-- | src/libcharon/sa/shunt_manager.h | 69 | ||||
-rw-r--r-- | src/libhydra/kernel/kernel_ipsec.c | 4 | ||||
-rw-r--r-- | src/libhydra/kernel/kernel_ipsec.h | 4 | ||||
-rw-r--r-- | src/starter/confread.c | 4 | ||||
-rw-r--r-- | src/starter/starterstroke.c | 29 |
13 files changed, 432 insertions, 27 deletions
diff --git a/src/libcharon/Makefile.am b/src/libcharon/Makefile.am index 27bea75a2..8455604c1 100644 --- a/src/libcharon/Makefile.am +++ b/src/libcharon/Makefile.am @@ -72,6 +72,7 @@ sa/ike_sa_id.c sa/ike_sa_id.h \ sa/ike_sa_manager.c sa/ike_sa_manager.h \ sa/task_manager.c sa/task_manager.h \ sa/keymat.c sa/keymat.h \ +sa/shunt_manager.c sa/shunt_manager.h \ sa/trap_manager.c sa/trap_manager.h \ sa/tasks/child_create.c sa/tasks/child_create.h \ sa/tasks/child_delete.c sa/tasks/child_delete.h \ diff --git a/src/libcharon/daemon.c b/src/libcharon/daemon.c index a2fe6aea5..9bdced122 100644 --- a/src/libcharon/daemon.c +++ b/src/libcharon/daemon.c @@ -115,6 +115,7 @@ static void destroy(private_daemon_t *this) #endif /* CAPABILITIES_LIBCAP */ DESTROY_IF(this->kernel_handler); DESTROY_IF(this->public.traps); + DESTROY_IF(this->public.shunts); DESTROY_IF(this->public.ike_sa_manager); DESTROY_IF(this->public.controller); DESTROY_IF(this->public.eap); @@ -294,6 +295,7 @@ private_daemon_t *daemon_create() this->public.backends = backend_manager_create(); this->public.socket = socket_manager_create(); this->public.traps = trap_manager_create(); + this->public.shunts = shunt_manager_create(); this->kernel_handler = kernel_handler_create(); #ifdef CAPABILITIES diff --git a/src/libcharon/daemon.h b/src/libcharon/daemon.h index 04f1fc249..a75237881 100644 --- a/src/libcharon/daemon.h +++ b/src/libcharon/daemon.h @@ -146,6 +146,7 @@ typedef struct daemon_t daemon_t; #include <bus/listeners/sys_logger.h> #include <sa/ike_sa_manager.h> #include <sa/trap_manager.h> +#include <sa/shunt_manager.h> #include <config/backend_manager.h> #include <sa/authenticators/eap/eap_manager.h> #include <sa/authenticators/eap/sim_manager.h> @@ -194,6 +195,11 @@ struct daemon_t { trap_manager_t *traps; /** + * Manager for shunt PASS|DROP policies + */ + shunt_manager_t *shunts; + + /** * Manager for the different configuration backends. */ backend_manager_t *backends; diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c index a657e9008..f09c74155 100644 --- a/src/libcharon/plugins/stroke/stroke_config.c +++ b/src/libcharon/plugins/stroke/stroke_config.c @@ -328,6 +328,9 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this, case AUTH_CLASS_EAP: auth = "eap"; break; + case AUTH_CLASS_ANY: + auth = "any"; + break; } } else diff --git a/src/libcharon/plugins/stroke/stroke_control.c b/src/libcharon/plugins/stroke/stroke_control.c index 7df225af2..95576482b 100644 --- a/src/libcharon/plugins/stroke/stroke_control.c +++ b/src/libcharon/plugins/stroke/stroke_control.c @@ -15,7 +15,9 @@ #include "stroke_control.h" +#include <hydra.h> #include <daemon.h> + #include <processing/jobs/delete_ike_sa_job.h> #include <processing/jobs/rekey_ike_sa_job.h> #include <processing/jobs/rekey_child_sa_job.h> @@ -521,18 +523,37 @@ METHOD(stroke_control_t, purge_ike, void, } /** - * call charon to install a trap + * call charon to install a shunt or trap */ static void charon_route(peer_cfg_t *peer_cfg, child_cfg_t *child_cfg, char *name, FILE *out) { - if (charon->traps->install(charon->traps, peer_cfg, child_cfg)) + ipsec_mode_t mode; + + mode = child_cfg->get_mode(child_cfg); + if (mode == MODE_PASS || mode == MODE_DROP) { - fprintf(out, "'%s' routed\n", name); + if (charon->shunts->install(charon->shunts, child_cfg)) + { + fprintf(out, "'%s' shunt %N policy installed\n", + name, ipsec_mode_names, mode); + } + else + { + fprintf(out, "'%s' shunt %N policy installation failed\n", + name, ipsec_mode_names, mode); + } } else - { - fprintf(out, "routing '%s' failed\n", name); + { + if (charon->traps->install(charon->traps, peer_cfg, child_cfg)) + { + fprintf(out, "'%s' routed\n", name); + } + else + { + fprintf(out, "routing '%s' failed\n", name); + } } } @@ -614,6 +635,13 @@ METHOD(stroke_control_t, unroute, void, child_sa_t *child_sa; enumerator_t *enumerator; u_int32_t id; + bool found = FALSE; + + if (charon->shunts->uninstall(charon->shunts, msg->unroute.name)) + { + fprintf(out, "shunt policy '%s' uninstalled\n", msg->unroute.name); + return; + } enumerator = charon->traps->create_enumerator(charon->traps); while (enumerator->enumerate(enumerator, NULL, &child_sa)) @@ -624,11 +652,15 @@ METHOD(stroke_control_t, unroute, void, enumerator->destroy(enumerator); charon->traps->uninstall(charon->traps, id); fprintf(out, "configuration '%s' unrouted\n", msg->unroute.name); - return; + found = TRUE; } } enumerator->destroy(enumerator); - fprintf(out, "configuration '%s' not found\n", msg->unroute.name); + + if (!found) + { + fprintf(out, "configuration '%s' not found\n", msg->unroute.name); + } } METHOD(stroke_control_t, destroy, void, diff --git a/src/libcharon/plugins/stroke/stroke_list.c b/src/libcharon/plugins/stroke/stroke_list.c index b1ac78a2f..d93164dae 100644 --- a/src/libcharon/plugins/stroke/stroke_list.c +++ b/src/libcharon/plugins/stroke/stroke_list.c @@ -398,6 +398,7 @@ METHOD(stroke_list_t, status, void, child_cfg_t *child_cfg; child_sa_t *child_sa; ike_sa_t *ike_sa; + linked_list_t *my_ts, *other_ts; bool first, found = FALSE; char *name = msg->status.name; u_int half_open; @@ -503,12 +504,11 @@ METHOD(stroke_list_t, status, void, children = peer_cfg->create_child_cfg_enumerator(peer_cfg); while (children->enumerate(children, &child_cfg)) { - linked_list_t *my_ts, *other_ts; - my_ts = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, NULL); other_ts = child_cfg->get_traffic_selectors(child_cfg, FALSE, NULL, NULL); - fprintf(out, "%12s: child: %#R=== %#R", child_cfg->get_name(child_cfg), - my_ts, other_ts); + fprintf(out, "%12s: child: %#R=== %#R%N", + child_cfg->get_name(child_cfg), my_ts, other_ts, + ipsec_mode_names, child_cfg->get_mode(child_cfg)); my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy)); other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy)); @@ -524,10 +524,39 @@ METHOD(stroke_list_t, status, void, enumerator->destroy(enumerator); } + /* Enumerate shunt policies */ + first = TRUE; + enumerator = charon->shunts->create_enumerator(charon->shunts); + while (enumerator->enumerate(enumerator, &child_cfg)) + { + if (name && !streq(name, child_cfg->get_name(child_cfg))) + { + continue; + } + if (first) + { + fprintf(out, "Shunted Connections:\n"); + first = FALSE; + } + my_ts = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, NULL); + other_ts = child_cfg->get_traffic_selectors(child_cfg, FALSE, NULL, NULL); + fprintf(out, "%12s: %#R=== %#R%N\n", + child_cfg->get_name(child_cfg), my_ts, other_ts, + ipsec_mode_names, child_cfg->get_mode(child_cfg)); + my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy)); + other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy)); + } + enumerator->destroy(enumerator); + + /* Enumerate traps */ first = TRUE; enumerator = charon->traps->create_enumerator(charon->traps); while (enumerator->enumerate(enumerator, NULL, &child_sa)) { + if (name && !streq(name, child_sa->get_name(child_sa))) + { + continue; + } if (first) { fprintf(out, "Routed Connections:\n"); diff --git a/src/libcharon/processing/jobs/start_action_job.c b/src/libcharon/processing/jobs/start_action_job.c index 63b9d7dcc..8f924bc15 100644 --- a/src/libcharon/processing/jobs/start_action_job.c +++ b/src/libcharon/processing/jobs/start_action_job.c @@ -42,6 +42,7 @@ METHOD(job_t, execute, void, enumerator_t *enumerator, *children; peer_cfg_t *peer_cfg; child_cfg_t *child_cfg; + ipsec_mode_t mode; char *name; enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends, @@ -69,7 +70,16 @@ METHOD(job_t, execute, void, break; case ACTION_ROUTE: DBG1(DBG_JOB, "start action: route '%s'", name); - charon->traps->install(charon->traps, peer_cfg, child_cfg); + mode = child_cfg->get_mode(child_cfg); + if (mode == MODE_PASS || mode == MODE_DROP) + { + charon->shunts->install(charon->shunts, child_cfg); + } + else + { + charon->traps->install(charon->traps, peer_cfg, + child_cfg); + } break; case ACTION_NONE: break; diff --git a/src/libcharon/sa/shunt_manager.c b/src/libcharon/sa/shunt_manager.c new file mode 100644 index 000000000..d33ca0ed9 --- /dev/null +++ b/src/libcharon/sa/shunt_manager.c @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2011 Andreas Steffen + * HSR 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. + */ + +#include "shunt_manager.h" + +#include <hydra.h> +#include <daemon.h> +#include <threading/rwlock.h> +#include <utils/linked_list.h> + + +typedef struct private_shunt_manager_t private_shunt_manager_t; + +/** + * Private data of an shunt_manager_t object. + */ +struct private_shunt_manager_t { + + /** + * Public shunt_manager_t interface. + */ + shunt_manager_t public; + + /** + * Installed shunts, as child_cfg_t + */ + linked_list_t *shunts; +}; + +/** + * Install in and out shunt policies in the kernel + */ +static bool install_shunt_policy(child_cfg_t *child) +{ + enumerator_t *e_my_ts, *e_other_ts; + linked_list_t *my_ts_list, *other_ts_list; + traffic_selector_t *my_ts, *other_ts; + policy_type_t policy_type; + status_t status = SUCCESS; + ipsec_sa_cfg_t sa = { .mode = MODE_TRANSPORT }; + + policy_type = (child->get_mode(child) == MODE_PASS) ? + POLICY_PASS : POLICY_DROP; + my_ts_list = child->get_traffic_selectors(child, TRUE, NULL, NULL); + other_ts_list = child->get_traffic_selectors(child, FALSE, NULL, NULL); + + /* enumerate pairs of traffic selectors */ + e_my_ts = my_ts_list->create_enumerator(my_ts_list); + while (e_my_ts->enumerate(e_my_ts, &my_ts)) + { + e_other_ts = other_ts_list->create_enumerator(other_ts_list); + while (e_other_ts->enumerate(e_other_ts, &other_ts)) + { + /* install out policy */ + status |= hydra->kernel_interface->add_policy( + hydra->kernel_interface, NULL, NULL, + my_ts, other_ts, POLICY_OUT, policy_type, + &sa, child->get_mark(child, FALSE), FALSE); + + /* install in policy */ + status |= hydra->kernel_interface->add_policy( + hydra->kernel_interface, NULL, NULL, + other_ts, my_ts, POLICY_IN, policy_type, + &sa, child->get_mark(child, TRUE), FALSE); + + /* install forward policy */ + status |= hydra->kernel_interface->add_policy( + hydra->kernel_interface, NULL, NULL, + other_ts, my_ts, POLICY_FWD, policy_type, + &sa, child->get_mark(child, TRUE), FALSE); + } + e_other_ts->destroy(e_other_ts); + } + e_my_ts->destroy(e_my_ts); + + my_ts_list->destroy_offset(my_ts_list, + offsetof(traffic_selector_t, destroy)); + other_ts_list->destroy_offset(other_ts_list, + offsetof(traffic_selector_t, destroy)); + + return status == SUCCESS; +} + +METHOD(shunt_manager_t, install, bool, + private_shunt_manager_t *this, child_cfg_t *child) +{ + enumerator_t *enumerator; + child_cfg_t *child_cfg; + bool found = FALSE; + + /* check if not already installed */ + enumerator = this->shunts->create_enumerator(this->shunts); + while (enumerator->enumerate(enumerator, &child_cfg)) + { + if (streq(child_cfg->get_name(child_cfg), child->get_name(child))) + { + found = TRUE; + break; + } + } + enumerator->destroy(enumerator); + + if (found) + { + DBG1(DBG_CFG, "shunt %N policy '%s' already installed", + ipsec_mode_names, child->get_mode(child), child->get_name(child)); + return TRUE; + } + this->shunts->insert_last(this->shunts, child->get_ref(child)); + + return install_shunt_policy(child); +} + +/** + * Uninstall in and out shunt policies in the kernel + */ +static void uninstall_shunt_policy(child_cfg_t *child) +{ + enumerator_t *e_my_ts, *e_other_ts; + linked_list_t *my_ts_list, *other_ts_list; + traffic_selector_t *my_ts, *other_ts; + status_t status = SUCCESS; + + my_ts_list = child->get_traffic_selectors(child, TRUE, NULL, NULL); + other_ts_list = child->get_traffic_selectors(child, FALSE, NULL, NULL); + + /* enumerate pairs of traffic selectors */ + e_my_ts = my_ts_list->create_enumerator(my_ts_list); + while (e_my_ts->enumerate(e_my_ts, &my_ts)) + { + e_other_ts = other_ts_list->create_enumerator(other_ts_list); + while (e_other_ts->enumerate(e_other_ts, &other_ts)) + { + /* uninstall out policy */ + status |= hydra->kernel_interface->del_policy( + hydra->kernel_interface, my_ts, other_ts, + POLICY_OUT, child->get_mark(child, FALSE), FALSE); + + /* uninstall in policy */ + status |= hydra->kernel_interface->del_policy( + hydra->kernel_interface, other_ts, my_ts, + POLICY_IN, child->get_mark(child, TRUE), FALSE); + + /* uninstall forward policy */ + status |= hydra->kernel_interface->del_policy( + hydra->kernel_interface, other_ts, my_ts, + POLICY_FWD, child->get_mark(child, TRUE), FALSE); + } + e_other_ts->destroy(e_other_ts); + } + e_my_ts->destroy(e_my_ts); + + my_ts_list->destroy_offset(my_ts_list, + offsetof(traffic_selector_t, destroy)); + other_ts_list->destroy_offset(other_ts_list, + offsetof(traffic_selector_t, destroy)); + + if (status != SUCCESS) + { + DBG1(DBG_CFG, "uninstalling shunt %N 'policy %s' failed", + ipsec_mode_names, child->get_mode(child), child->get_name(child)); + } +} + +METHOD(shunt_manager_t, uninstall, bool, + private_shunt_manager_t *this, char *name) +{ + enumerator_t *enumerator; + child_cfg_t *child, *found = NULL; + + enumerator = this->shunts->create_enumerator(this->shunts); + while (enumerator->enumerate(enumerator, &child)) + { + if (streq(name, child->get_name(child))) + { + this->shunts->remove_at(this->shunts, enumerator); + found = child; + break; + } + } + enumerator->destroy(enumerator); + + if (!found) + { + return FALSE; + } + uninstall_shunt_policy(child); + return TRUE; +} + +METHOD(shunt_manager_t, create_enumerator, enumerator_t*, + private_shunt_manager_t *this) +{ + return this->shunts->create_enumerator(this->shunts); +} + +METHOD(shunt_manager_t, destroy, void, + private_shunt_manager_t *this) +{ + child_cfg_t *child; + + while (this->shunts->remove_last(this->shunts, (void**)&child) == SUCCESS) + { + uninstall_shunt_policy(child); + child->destroy(child); + } + this->shunts->destroy(this->shunts); + free(this); +} + +/** + * See header + */ +shunt_manager_t *shunt_manager_create() +{ + private_shunt_manager_t *this; + + INIT(this, + .public = { + .install = _install, + .uninstall = _uninstall, + .create_enumerator = _create_enumerator, + .destroy = _destroy, + }, + .shunts = linked_list_create(), + ); + + return &this->public; +} + diff --git a/src/libcharon/sa/shunt_manager.h b/src/libcharon/sa/shunt_manager.h new file mode 100644 index 000000000..12ff08558 --- /dev/null +++ b/src/libcharon/sa/shunt_manager.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2011 Andreas Steffen + * HSR 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. + */ + +/** + * @defgroup shunt_manager shunt_manager + * @{ @ingroup sa + */ + +#ifndef SHUNT_MANAGER_H_ +#define SHUNT_MANAGER_H_ + +#include <library.h> +#include <utils/enumerator.h> +#include <config/child_cfg.h> + +typedef struct shunt_manager_t shunt_manager_t; + +/** + * Manage PASS and DROP shunt policy excepting traffic from IPsec SAs. + */ +struct shunt_manager_t { + + /** + * Install a policy as a shunt. + * + * @param child child configuration to install as a shunt + * @return TRUE if installed successfully + */ + bool (*install)(shunt_manager_t *this, child_cfg_t *child); + + /** + * Uninstall a shunt policy. + * + * @param name name of child configuration to uninstall as a shunt + * @return TRUE if uninstalled successfully + */ + bool (*uninstall)(shunt_manager_t *this, char *name); + + /** + * Create an enumerator over all installed shunts. + * + * @return enumerator over (child_sa_t) + */ + enumerator_t* (*create_enumerator)(shunt_manager_t *this); + + /** + * Destroy a shunt_manager_t. + */ + void (*destroy)(shunt_manager_t *this); +}; + +/** + * Create a shunt_manager instance. + */ +shunt_manager_t *shunt_manager_create(); + +#endif /** SHUNT_MANAGER_H_ @}*/ diff --git a/src/libhydra/kernel/kernel_ipsec.c b/src/libhydra/kernel/kernel_ipsec.c index 383685426..9035196b7 100644 --- a/src/libhydra/kernel/kernel_ipsec.c +++ b/src/libhydra/kernel/kernel_ipsec.c @@ -15,10 +15,12 @@ #include "kernel_ipsec.h" -ENUM(ipsec_mode_names, MODE_TRANSPORT, MODE_BEET, +ENUM(ipsec_mode_names, MODE_TRANSPORT, MODE_DROP, "TRANSPORT", "TUNNEL", "BEET", + "PASS", + "DROP" ); ENUM(policy_dir_names, POLICY_IN, POLICY_FWD, diff --git a/src/libhydra/kernel/kernel_ipsec.h b/src/libhydra/kernel/kernel_ipsec.h index ef36efd11..e7b62ad1f 100644 --- a/src/libhydra/kernel/kernel_ipsec.h +++ b/src/libhydra/kernel/kernel_ipsec.h @@ -47,6 +47,10 @@ enum ipsec_mode_t { MODE_TUNNEL, /** BEET mode, tunnel mode but fixed, bound inner addresses */ MODE_BEET, + /** passthrough policy for traffic without an IPsec SA */ + MODE_PASS, + /** drop policy discarding traffic */ + MODE_DROP }; /** diff --git a/src/starter/confread.c b/src/starter/confread.c index 1e7daa6a9..5c9478791 100644 --- a/src/starter/confread.c +++ b/src/starter/confread.c @@ -609,7 +609,7 @@ static void load_conn(starter_conn_t *conn, kw_list_t *kw, starter_config_t *cfg case KW_AUTHBY: conn->policy &= ~(POLICY_ID_AUTH_MASK | POLICY_ENCRYPT); - if (!(streq(kw->value, "never") || streq(kw->value, "eap"))) + if (!streq(kw->value, "never")) { char *value = kw->value; char *second = strchr(kw->value, '|'); @@ -636,7 +636,7 @@ static void load_conn(starter_conn_t *conn, kw_list_t *kw, starter_config_t *cfg { conn->policy |= POLICY_XAUTH_RSASIG | POLICY_ENCRYPT; } - else if (streq(value, "xauthpsk")) + else if (streq(value, "xauthpsk") || streq(value, "eap")) { conn->policy |= POLICY_XAUTH_PSK | POLICY_ENCRYPT; } diff --git a/src/starter/starterstroke.c b/src/starter/starterstroke.c index cfb9bc6fa..6ead95c8b 100644 --- a/src/starter/starterstroke.c +++ b/src/starter/starterstroke.c @@ -24,6 +24,8 @@ #include <netinet/in.h> #include <arpa/inet.h> +#include <credentials/auth_cfg.h> + #include <freeswan.h> #include <constants.h> @@ -39,15 +41,6 @@ #define IPV4_LEN 4 #define IPV6_LEN 16 -/** - * Authentication methods, must be the same as in charons authenticator.h - */ -enum auth_method_t { - AUTH_PUBKEY = 1, - AUTH_PSK = 2, - AUTH_EAP = 3 -}; - static char* push_string(stroke_msg_t *msg, char *string) { unsigned long string_start = msg->length; @@ -202,15 +195,19 @@ int starter_stroke_add_conn(starter_config_t *cfg, starter_conn_t *conn) /* PUBKEY is preferred to PSK and EAP */ if (conn->policy & POLICY_PUBKEY) { - msg.add_conn.auth_method = AUTH_PUBKEY; + msg.add_conn.auth_method = AUTH_CLASS_PUBKEY; } else if (conn->policy & POLICY_PSK) { - msg.add_conn.auth_method = AUTH_PSK; + msg.add_conn.auth_method = AUTH_CLASS_PSK; + } + else if (conn->policy & POLICY_XAUTH_PSK) + { + msg.add_conn.auth_method = AUTH_CLASS_EAP; } else { - msg.add_conn.auth_method = AUTH_EAP; + msg.add_conn.auth_method = AUTH_CLASS_ANY; } msg.add_conn.eap_type = conn->eap_type; msg.add_conn.eap_vendor = conn->eap_vendor; @@ -230,6 +227,14 @@ int starter_stroke_add_conn(starter_config_t *cfg, starter_conn_t *conn) msg.add_conn.mode = MODE_TRANSPORT; msg.add_conn.proxy_mode = TRUE; } + else if (conn->policy & POLICY_SHUNT_PASS) + { + msg.add_conn.mode = MODE_PASS; + } + else if (conn->policy & (POLICY_SHUNT_DROP | POLICY_SHUNT_REJECT)) + { + msg.add_conn.mode = MODE_DROP; + } else { msg.add_conn.mode = MODE_TRANSPORT; |