mirror of
https://github.com/strongswan/strongswan.git
synced 2025-10-05 00:00:45 -04:00
shunt-manager: Add an optional namespace for each shunt
This will allow us to reuse the names of child configs e.g. when they are defined in different connections.
This commit is contained in:
parent
ed105f45af
commit
7a0fdbab42
@ -79,7 +79,7 @@ static void bypass_policy_destroy(bypass_policy_t *this)
|
||||
ts = traffic_selector_create_from_subnet(this->net->clone(this->net),
|
||||
this->mask, 0, 0, 65535);
|
||||
DBG1(DBG_IKE, "uninstalling bypass policy for %R", ts);
|
||||
charon->shunts->uninstall(charon->shunts,
|
||||
charon->shunts->uninstall(charon->shunts, "bypass-lan",
|
||||
this->cfg->get_name(this->cfg));
|
||||
this->cfg->destroy(this->cfg);
|
||||
ts->destroy(ts);
|
||||
@ -173,7 +173,7 @@ static job_requeue_t update_bypass(private_bypass_lan_listener_t *this)
|
||||
cfg = child_cfg_create(name, &child);
|
||||
cfg->add_traffic_selector(cfg, FALSE, ts->clone(ts));
|
||||
cfg->add_traffic_selector(cfg, TRUE, ts);
|
||||
charon->shunts->install(charon->shunts, cfg);
|
||||
charon->shunts->install(charon->shunts, "bypass-lan", cfg);
|
||||
DBG1(DBG_IKE, "installed bypass policy for %R", ts);
|
||||
|
||||
INIT(found,
|
||||
|
@ -641,7 +641,7 @@ static void charon_route(peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
|
||||
mode = child_cfg->get_mode(child_cfg);
|
||||
if (mode == MODE_PASS || mode == MODE_DROP)
|
||||
{
|
||||
if (charon->shunts->install(charon->shunts, child_cfg))
|
||||
if (charon->shunts->install(charon->shunts, NULL, child_cfg))
|
||||
{
|
||||
fprintf(out, "'%s' shunt %N policy installed\n",
|
||||
name, ipsec_mode_names, mode);
|
||||
@ -733,7 +733,7 @@ METHOD(stroke_control_t, unroute, void,
|
||||
enumerator_t *enumerator;
|
||||
uint32_t id = 0;
|
||||
|
||||
if (charon->shunts->uninstall(charon->shunts, msg->unroute.name))
|
||||
if (charon->shunts->uninstall(charon->shunts, NULL, msg->unroute.name))
|
||||
{
|
||||
fprintf(out, "shunt policy '%s' uninstalled\n", msg->unroute.name);
|
||||
return;
|
||||
|
@ -603,7 +603,7 @@ METHOD(stroke_list_t, status, void,
|
||||
/* Enumerate shunt policies */
|
||||
first = TRUE;
|
||||
enumerator = charon->shunts->create_enumerator(charon->shunts);
|
||||
while (enumerator->enumerate(enumerator, &child_cfg))
|
||||
while (enumerator->enumerate(enumerator, NULL, &child_cfg))
|
||||
{
|
||||
if (name && !streq(name, child_cfg->get_name(child_cfg)))
|
||||
{
|
||||
|
@ -235,7 +235,7 @@ static job_requeue_t add_exclude_async(entry_t *entry)
|
||||
enumerator->destroy(enumerator);
|
||||
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
|
||||
|
||||
charon->shunts->install(charon->shunts, child_cfg);
|
||||
charon->shunts->install(charon->shunts, "unity", child_cfg);
|
||||
child_cfg->destroy(child_cfg);
|
||||
|
||||
DBG1(DBG_IKE, "installed %N bypass policy for %R",
|
||||
@ -310,7 +310,8 @@ static bool remove_exclude(private_unity_handler_t *this, chunk_t data)
|
||||
DBG1(DBG_IKE, "uninstalling %N bypass policy for %R",
|
||||
configuration_attribute_type_names, UNITY_LOCAL_LAN, ts);
|
||||
ts->destroy(ts);
|
||||
success = charon->shunts->uninstall(charon->shunts, name) && success;
|
||||
success = charon->shunts->uninstall(charon->shunts, "unity",
|
||||
name) && success;
|
||||
}
|
||||
list->destroy(list);
|
||||
return success;
|
||||
|
@ -1757,7 +1757,7 @@ static void run_start_action(private_vici_config_t *this, peer_cfg_t *peer_cfg,
|
||||
{
|
||||
case MODE_PASS:
|
||||
case MODE_DROP:
|
||||
charon->shunts->install(charon->shunts, child_cfg);
|
||||
charon->shunts->install(charon->shunts, NULL, child_cfg);
|
||||
break;
|
||||
default:
|
||||
charon->traps->install(charon->traps, peer_cfg, child_cfg,
|
||||
@ -1865,7 +1865,7 @@ static void clear_start_action(private_vici_config_t *this, char *peer_name,
|
||||
{
|
||||
case MODE_PASS:
|
||||
case MODE_DROP:
|
||||
charon->shunts->uninstall(charon->shunts, name);
|
||||
charon->shunts->uninstall(charon->shunts, NULL, name);
|
||||
break;
|
||||
default:
|
||||
enumerator = charon->traps->create_enumerator(charon->traps);
|
||||
|
@ -565,7 +565,7 @@ CALLBACK(install, vici_message_t*,
|
||||
{
|
||||
case MODE_PASS:
|
||||
case MODE_DROP:
|
||||
ok = charon->shunts->install(charon->shunts, child_cfg);
|
||||
ok = charon->shunts->install(charon->shunts, NULL, child_cfg);
|
||||
break;
|
||||
default:
|
||||
ok = charon->traps->install(charon->traps, peer_cfg, child_cfg,
|
||||
@ -594,7 +594,7 @@ CALLBACK(uninstall, vici_message_t*,
|
||||
|
||||
DBG1(DBG_CFG, "vici uninstall '%s'", child);
|
||||
|
||||
if (charon->shunts->uninstall(charon->shunts, child))
|
||||
if (charon->shunts->uninstall(charon->shunts, NULL, child))
|
||||
{
|
||||
return send_reply(this, NULL);
|
||||
}
|
||||
|
@ -580,7 +580,7 @@ CALLBACK(list_policies, vici_message_t*,
|
||||
if (drop || pass)
|
||||
{
|
||||
enumerator = charon->shunts->create_enumerator(charon->shunts);
|
||||
while (enumerator->enumerate(enumerator, &child_cfg))
|
||||
while (enumerator->enumerate(enumerator, NULL, &child_cfg))
|
||||
{
|
||||
if (child && !streq(child, child_cfg->get_name(child_cfg)))
|
||||
{
|
||||
|
@ -68,7 +68,8 @@ METHOD(job_t, execute, job_requeue_t,
|
||||
mode = child_cfg->get_mode(child_cfg);
|
||||
if (mode == MODE_PASS || mode == MODE_DROP)
|
||||
{
|
||||
charon->shunts->install(charon->shunts, child_cfg);
|
||||
charon->shunts->install(charon->shunts, NULL,
|
||||
child_cfg);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -36,7 +36,7 @@ struct private_shunt_manager_t {
|
||||
shunt_manager_t public;
|
||||
|
||||
/**
|
||||
* Installed shunts, as child_cfg_t
|
||||
* Installed shunts, as entry_t
|
||||
*/
|
||||
linked_list_t *shunts;
|
||||
|
||||
@ -56,6 +56,32 @@ struct private_shunt_manager_t {
|
||||
rwlock_condvar_t *condvar;
|
||||
};
|
||||
|
||||
/**
|
||||
* Config entry for a shunt
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* Configured namespace
|
||||
*/
|
||||
char *ns;
|
||||
|
||||
/**
|
||||
* Child config
|
||||
*/
|
||||
child_cfg_t *cfg;
|
||||
|
||||
} entry_t;
|
||||
|
||||
/**
|
||||
* Destroy a config entry
|
||||
*/
|
||||
static void entry_destroy(entry_t *this)
|
||||
{
|
||||
this->cfg->destroy(this->cfg);
|
||||
free(this->ns);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Install in and out shunt policies in the kernel
|
||||
*/
|
||||
@ -162,10 +188,10 @@ static bool install_shunt_policy(child_cfg_t *child)
|
||||
}
|
||||
|
||||
METHOD(shunt_manager_t, install, bool,
|
||||
private_shunt_manager_t *this, child_cfg_t *child)
|
||||
private_shunt_manager_t *this, char *ns, child_cfg_t *cfg)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
child_cfg_t *child_cfg;
|
||||
entry_t *entry;
|
||||
bool found = FALSE, success;
|
||||
|
||||
/* check if not already installed */
|
||||
@ -176,9 +202,10 @@ METHOD(shunt_manager_t, install, bool,
|
||||
return FALSE;
|
||||
}
|
||||
enumerator = this->shunts->create_enumerator(this->shunts);
|
||||
while (enumerator->enumerate(enumerator, &child_cfg))
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (streq(child_cfg->get_name(child_cfg), child->get_name(child)))
|
||||
if (streq(ns, entry->ns) &&
|
||||
streq(cfg->get_name(cfg), entry->cfg->get_name(entry->cfg)))
|
||||
{
|
||||
found = TRUE;
|
||||
break;
|
||||
@ -188,21 +215,25 @@ METHOD(shunt_manager_t, install, bool,
|
||||
if (found)
|
||||
{
|
||||
DBG1(DBG_CFG, "shunt %N policy '%s' already installed",
|
||||
ipsec_mode_names, child->get_mode(child), child->get_name(child));
|
||||
ipsec_mode_names, cfg->get_mode(cfg), cfg->get_name(cfg));
|
||||
this->lock->unlock(this->lock);
|
||||
return TRUE;
|
||||
}
|
||||
this->shunts->insert_last(this->shunts, child->get_ref(child));
|
||||
INIT(entry,
|
||||
.ns = strdupnull(ns),
|
||||
.cfg = cfg->get_ref(cfg),
|
||||
);
|
||||
this->shunts->insert_last(this->shunts, entry);
|
||||
this->installing++;
|
||||
this->lock->unlock(this->lock);
|
||||
|
||||
success = install_shunt_policy(child);
|
||||
success = install_shunt_policy(cfg);
|
||||
|
||||
this->lock->write_lock(this->lock);
|
||||
if (!success)
|
||||
{
|
||||
this->shunts->remove(this->shunts, child, NULL);
|
||||
child->destroy(child);
|
||||
this->shunts->remove(this->shunts, entry, NULL);
|
||||
entry_destroy(entry);
|
||||
}
|
||||
this->installing--;
|
||||
this->condvar->signal(this->condvar);
|
||||
@ -320,19 +351,20 @@ static void uninstall_shunt_policy(child_cfg_t *child)
|
||||
}
|
||||
|
||||
METHOD(shunt_manager_t, uninstall, bool,
|
||||
private_shunt_manager_t *this, char *name)
|
||||
private_shunt_manager_t *this, char *ns, char *name)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
child_cfg_t *child, *found = NULL;
|
||||
entry_t *entry, *found = NULL;
|
||||
|
||||
this->lock->write_lock(this->lock);
|
||||
enumerator = this->shunts->create_enumerator(this->shunts);
|
||||
while (enumerator->enumerate(enumerator, &child))
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (streq(name, child->get_name(child)))
|
||||
if (streq(ns, entry->ns) &&
|
||||
streq(name, entry->cfg->get_name(entry->cfg)))
|
||||
{
|
||||
this->shunts->remove_at(this->shunts, enumerator);
|
||||
found = child;
|
||||
found = entry;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -343,8 +375,19 @@ METHOD(shunt_manager_t, uninstall, bool,
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
uninstall_shunt_policy(child);
|
||||
child->destroy(child);
|
||||
uninstall_shunt_policy(found->cfg);
|
||||
entry_destroy(found);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
CALLBACK(filter_entries, bool,
|
||||
void *unused, entry_t **entry, char **ns, void **in, child_cfg_t **cfg)
|
||||
{
|
||||
if (ns)
|
||||
{
|
||||
*ns = (*entry)->ns;
|
||||
}
|
||||
*cfg = (*entry)->cfg;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -352,25 +395,26 @@ METHOD(shunt_manager_t, create_enumerator, enumerator_t*,
|
||||
private_shunt_manager_t *this)
|
||||
{
|
||||
this->lock->read_lock(this->lock);
|
||||
return enumerator_create_cleaner(
|
||||
return enumerator_create_filter(
|
||||
this->shunts->create_enumerator(this->shunts),
|
||||
(void*)this->lock->unlock, this->lock);
|
||||
(void*)filter_entries, this->lock,
|
||||
(void*)this->lock->unlock);
|
||||
}
|
||||
|
||||
METHOD(shunt_manager_t, flush, void,
|
||||
private_shunt_manager_t *this)
|
||||
{
|
||||
child_cfg_t *child;
|
||||
entry_t *entry;
|
||||
|
||||
this->lock->write_lock(this->lock);
|
||||
while (this->installing)
|
||||
{
|
||||
this->condvar->wait(this->condvar, this->lock);
|
||||
}
|
||||
while (this->shunts->remove_last(this->shunts, (void**)&child) == SUCCESS)
|
||||
while (this->shunts->remove_last(this->shunts, (void**)&entry) == SUCCESS)
|
||||
{
|
||||
uninstall_shunt_policy(child);
|
||||
child->destroy(child);
|
||||
uninstall_shunt_policy(entry->cfg);
|
||||
entry_destroy(entry);
|
||||
}
|
||||
this->installing = INSTALL_DISABLED;
|
||||
this->lock->unlock(this->lock);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Tobias Brunner
|
||||
* Copyright (C) 2015-2016 Tobias Brunner
|
||||
* Copyright (C) 2011 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
@ -36,23 +36,26 @@ struct shunt_manager_t {
|
||||
/**
|
||||
* Install a policy as a shunt.
|
||||
*
|
||||
* @param child child configuration to install as a shunt
|
||||
* @param ns optional namespace (e.g. name of a connection or
|
||||
* plugin), cloned
|
||||
* @param child child configuration to install as a shunt
|
||||
* @return TRUE if installed successfully
|
||||
*/
|
||||
bool (*install)(shunt_manager_t *this, child_cfg_t *child);
|
||||
bool (*install)(shunt_manager_t *this, char *ns, child_cfg_t *child);
|
||||
|
||||
/**
|
||||
* Uninstall a shunt policy.
|
||||
*
|
||||
* @param ns namespace (same as given during installation)
|
||||
* @param name name of child configuration to uninstall as a shunt
|
||||
* @return TRUE if uninstalled successfully
|
||||
*/
|
||||
bool (*uninstall)(shunt_manager_t *this, char *name);
|
||||
bool (*uninstall)(shunt_manager_t *this, char *ns, char *name);
|
||||
|
||||
/**
|
||||
* Create an enumerator over all installed shunts.
|
||||
*
|
||||
* @return enumerator over (child_sa_t)
|
||||
* @return enumerator over (char*, child_cfg_t*)
|
||||
*/
|
||||
enumerator_t* (*create_enumerator)(shunt_manager_t *this);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user