mirror of
https://github.com/strongswan/strongswan.git
synced 2025-10-15 00:00:16 -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),
|
ts = traffic_selector_create_from_subnet(this->net->clone(this->net),
|
||||||
this->mask, 0, 0, 65535);
|
this->mask, 0, 0, 65535);
|
||||||
DBG1(DBG_IKE, "uninstalling bypass policy for %R", ts);
|
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->get_name(this->cfg));
|
||||||
this->cfg->destroy(this->cfg);
|
this->cfg->destroy(this->cfg);
|
||||||
ts->destroy(ts);
|
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 = child_cfg_create(name, &child);
|
||||||
cfg->add_traffic_selector(cfg, FALSE, ts->clone(ts));
|
cfg->add_traffic_selector(cfg, FALSE, ts->clone(ts));
|
||||||
cfg->add_traffic_selector(cfg, TRUE, 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);
|
DBG1(DBG_IKE, "installed bypass policy for %R", ts);
|
||||||
|
|
||||||
INIT(found,
|
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);
|
mode = child_cfg->get_mode(child_cfg);
|
||||||
if (mode == MODE_PASS || mode == MODE_DROP)
|
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",
|
fprintf(out, "'%s' shunt %N policy installed\n",
|
||||||
name, ipsec_mode_names, mode);
|
name, ipsec_mode_names, mode);
|
||||||
@ -733,7 +733,7 @@ METHOD(stroke_control_t, unroute, void,
|
|||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
uint32_t id = 0;
|
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);
|
fprintf(out, "shunt policy '%s' uninstalled\n", msg->unroute.name);
|
||||||
return;
|
return;
|
||||||
|
@ -603,7 +603,7 @@ METHOD(stroke_list_t, status, void,
|
|||||||
/* Enumerate shunt policies */
|
/* Enumerate shunt policies */
|
||||||
first = TRUE;
|
first = TRUE;
|
||||||
enumerator = charon->shunts->create_enumerator(charon->shunts);
|
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)))
|
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);
|
enumerator->destroy(enumerator);
|
||||||
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
|
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);
|
child_cfg->destroy(child_cfg);
|
||||||
|
|
||||||
DBG1(DBG_IKE, "installed %N bypass policy for %R",
|
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",
|
DBG1(DBG_IKE, "uninstalling %N bypass policy for %R",
|
||||||
configuration_attribute_type_names, UNITY_LOCAL_LAN, ts);
|
configuration_attribute_type_names, UNITY_LOCAL_LAN, ts);
|
||||||
ts->destroy(ts);
|
ts->destroy(ts);
|
||||||
success = charon->shunts->uninstall(charon->shunts, name) && success;
|
success = charon->shunts->uninstall(charon->shunts, "unity",
|
||||||
|
name) && success;
|
||||||
}
|
}
|
||||||
list->destroy(list);
|
list->destroy(list);
|
||||||
return success;
|
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_PASS:
|
||||||
case MODE_DROP:
|
case MODE_DROP:
|
||||||
charon->shunts->install(charon->shunts, child_cfg);
|
charon->shunts->install(charon->shunts, NULL, child_cfg);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
charon->traps->install(charon->traps, peer_cfg, child_cfg,
|
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_PASS:
|
||||||
case MODE_DROP:
|
case MODE_DROP:
|
||||||
charon->shunts->uninstall(charon->shunts, name);
|
charon->shunts->uninstall(charon->shunts, NULL, name);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
enumerator = charon->traps->create_enumerator(charon->traps);
|
enumerator = charon->traps->create_enumerator(charon->traps);
|
||||||
|
@ -565,7 +565,7 @@ CALLBACK(install, vici_message_t*,
|
|||||||
{
|
{
|
||||||
case MODE_PASS:
|
case MODE_PASS:
|
||||||
case MODE_DROP:
|
case MODE_DROP:
|
||||||
ok = charon->shunts->install(charon->shunts, child_cfg);
|
ok = charon->shunts->install(charon->shunts, NULL, child_cfg);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ok = charon->traps->install(charon->traps, peer_cfg, child_cfg,
|
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);
|
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);
|
return send_reply(this, NULL);
|
||||||
}
|
}
|
||||||
|
@ -580,7 +580,7 @@ CALLBACK(list_policies, vici_message_t*,
|
|||||||
if (drop || pass)
|
if (drop || pass)
|
||||||
{
|
{
|
||||||
enumerator = charon->shunts->create_enumerator(charon->shunts);
|
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)))
|
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);
|
mode = child_cfg->get_mode(child_cfg);
|
||||||
if (mode == MODE_PASS || mode == MODE_DROP)
|
if (mode == MODE_PASS || mode == MODE_DROP)
|
||||||
{
|
{
|
||||||
charon->shunts->install(charon->shunts, child_cfg);
|
charon->shunts->install(charon->shunts, NULL,
|
||||||
|
child_cfg);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -36,7 +36,7 @@ struct private_shunt_manager_t {
|
|||||||
shunt_manager_t public;
|
shunt_manager_t public;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Installed shunts, as child_cfg_t
|
* Installed shunts, as entry_t
|
||||||
*/
|
*/
|
||||||
linked_list_t *shunts;
|
linked_list_t *shunts;
|
||||||
|
|
||||||
@ -56,6 +56,32 @@ struct private_shunt_manager_t {
|
|||||||
rwlock_condvar_t *condvar;
|
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
|
* 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,
|
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;
|
enumerator_t *enumerator;
|
||||||
child_cfg_t *child_cfg;
|
entry_t *entry;
|
||||||
bool found = FALSE, success;
|
bool found = FALSE, success;
|
||||||
|
|
||||||
/* check if not already installed */
|
/* check if not already installed */
|
||||||
@ -176,9 +202,10 @@ METHOD(shunt_manager_t, install, bool,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
enumerator = this->shunts->create_enumerator(this->shunts);
|
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;
|
found = TRUE;
|
||||||
break;
|
break;
|
||||||
@ -188,21 +215,25 @@ METHOD(shunt_manager_t, install, bool,
|
|||||||
if (found)
|
if (found)
|
||||||
{
|
{
|
||||||
DBG1(DBG_CFG, "shunt %N policy '%s' already installed",
|
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);
|
this->lock->unlock(this->lock);
|
||||||
return TRUE;
|
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->installing++;
|
||||||
this->lock->unlock(this->lock);
|
this->lock->unlock(this->lock);
|
||||||
|
|
||||||
success = install_shunt_policy(child);
|
success = install_shunt_policy(cfg);
|
||||||
|
|
||||||
this->lock->write_lock(this->lock);
|
this->lock->write_lock(this->lock);
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
this->shunts->remove(this->shunts, child, NULL);
|
this->shunts->remove(this->shunts, entry, NULL);
|
||||||
child->destroy(child);
|
entry_destroy(entry);
|
||||||
}
|
}
|
||||||
this->installing--;
|
this->installing--;
|
||||||
this->condvar->signal(this->condvar);
|
this->condvar->signal(this->condvar);
|
||||||
@ -320,19 +351,20 @@ static void uninstall_shunt_policy(child_cfg_t *child)
|
|||||||
}
|
}
|
||||||
|
|
||||||
METHOD(shunt_manager_t, uninstall, bool,
|
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;
|
enumerator_t *enumerator;
|
||||||
child_cfg_t *child, *found = NULL;
|
entry_t *entry, *found = NULL;
|
||||||
|
|
||||||
this->lock->write_lock(this->lock);
|
this->lock->write_lock(this->lock);
|
||||||
enumerator = this->shunts->create_enumerator(this->shunts);
|
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);
|
this->shunts->remove_at(this->shunts, enumerator);
|
||||||
found = child;
|
found = entry;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -343,8 +375,19 @@ METHOD(shunt_manager_t, uninstall, bool,
|
|||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
uninstall_shunt_policy(child);
|
uninstall_shunt_policy(found->cfg);
|
||||||
child->destroy(child);
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,25 +395,26 @@ METHOD(shunt_manager_t, create_enumerator, enumerator_t*,
|
|||||||
private_shunt_manager_t *this)
|
private_shunt_manager_t *this)
|
||||||
{
|
{
|
||||||
this->lock->read_lock(this->lock);
|
this->lock->read_lock(this->lock);
|
||||||
return enumerator_create_cleaner(
|
return enumerator_create_filter(
|
||||||
this->shunts->create_enumerator(this->shunts),
|
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,
|
METHOD(shunt_manager_t, flush, void,
|
||||||
private_shunt_manager_t *this)
|
private_shunt_manager_t *this)
|
||||||
{
|
{
|
||||||
child_cfg_t *child;
|
entry_t *entry;
|
||||||
|
|
||||||
this->lock->write_lock(this->lock);
|
this->lock->write_lock(this->lock);
|
||||||
while (this->installing)
|
while (this->installing)
|
||||||
{
|
{
|
||||||
this->condvar->wait(this->condvar, this->lock);
|
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);
|
uninstall_shunt_policy(entry->cfg);
|
||||||
child->destroy(child);
|
entry_destroy(entry);
|
||||||
}
|
}
|
||||||
this->installing = INSTALL_DISABLED;
|
this->installing = INSTALL_DISABLED;
|
||||||
this->lock->unlock(this->lock);
|
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
|
* Copyright (C) 2011 Andreas Steffen
|
||||||
* HSR Hochschule fuer Technik Rapperswil
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
@ -36,23 +36,26 @@ struct shunt_manager_t {
|
|||||||
/**
|
/**
|
||||||
* Install a policy as a shunt.
|
* Install a policy 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
|
* @param child child configuration to install as a shunt
|
||||||
* @return TRUE if installed successfully
|
* @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.
|
* Uninstall a shunt policy.
|
||||||
*
|
*
|
||||||
|
* @param ns namespace (same as given during installation)
|
||||||
* @param name name of child configuration to uninstall as a shunt
|
* @param name name of child configuration to uninstall as a shunt
|
||||||
* @return TRUE if uninstalled successfully
|
* @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.
|
* 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);
|
enumerator_t* (*create_enumerator)(shunt_manager_t *this);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user