]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
shunt-manager: Add an optional namespace for each shunt
authorTobias Brunner <tobias@strongswan.org>
Wed, 16 Nov 2016 16:59:22 +0000 (17:59 +0100)
committerTobias Brunner <tobias@strongswan.org>
Thu, 16 Feb 2017 18:24:07 +0000 (19:24 +0100)
This will allow us to reuse the names of child configs e.g. when they
are defined in different connections.

src/libcharon/plugins/bypass_lan/bypass_lan_listener.c
src/libcharon/plugins/stroke/stroke_control.c
src/libcharon/plugins/stroke/stroke_list.c
src/libcharon/plugins/unity/unity_handler.c
src/libcharon/plugins/vici/vici_config.c
src/libcharon/plugins/vici/vici_control.c
src/libcharon/plugins/vici/vici_query.c
src/libcharon/processing/jobs/start_action_job.c
src/libcharon/sa/shunt_manager.c
src/libcharon/sa/shunt_manager.h

index 138f8fb0b100521422e416fba5dfe780d616d50b..e690028f207c069430f093da8ea78fc627020d81 100644 (file)
@@ -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,
index fb60d39730e9e8c1c64ca4bc77ef4a16d04a5d9c..7b0602cfbd85d911a240eabe5fa856b7ca54c19c 100644 (file)
@@ -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;
index cec26579da1074a374a78527cddedea02348e2ce..92e36866994de924a4ce416e029c20a40bdb5589 100644 (file)
@@ -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)))
                {
index 5707278233b6313f64d5b0fa095e9d5e5f8dbef4..25e0756b7582a4a331330c1038794ee0a1b4c1fe 100644 (file)
@@ -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;
index b16e23a5aabc6065a7cf0aab49c62eb7cfff8c60..dbbeb9e55b043b7aa312b00b95f05d8b19a9741b 100644 (file)
@@ -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);
index 59c21443733ca93e46b9df8d4a4dd9091d1d3d23..20d19252b641ddbe1596f511b41714f87c37c910 100644 (file)
@@ -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);
        }
index 3f7d71e79a21725fc7afdbda53fba31ceda70964..692cd7f5d7b8910929efa63022921c0a54666b89 100644 (file)
@@ -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)))
                        {
index 5e88ac230b862b62e9305ead936452e1c9973482..19f2052512c37a17f9c9eb380863f346ff111155 100644 (file)
@@ -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
                                        {
index 40e291be57d87e7c445ac2907ad673c10c94c00b..b0162751dbce166e7adbe9330d2c17c5fdf6abf3 100644 (file)
@@ -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);
index c43f5db3de7d37b3862a1e0e978a7b1c517b179c..f2b72103210b0c877a7d81b97b1ad5b2af5e42b5 100644 (file)
@@ -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);