aboutsummaryrefslogtreecommitdiffstats
path: root/main/strongswan/0011-shunt-manager-Add-flush-method-to-properly-uninstall.patch
diff options
context:
space:
mode:
Diffstat (limited to 'main/strongswan/0011-shunt-manager-Add-flush-method-to-properly-uninstall.patch')
-rw-r--r--main/strongswan/0011-shunt-manager-Add-flush-method-to-properly-uninstall.patch153
1 files changed, 153 insertions, 0 deletions
diff --git a/main/strongswan/0011-shunt-manager-Add-flush-method-to-properly-uninstall.patch b/main/strongswan/0011-shunt-manager-Add-flush-method-to-properly-uninstall.patch
new file mode 100644
index 0000000000..3aa6b561bc
--- /dev/null
+++ b/main/strongswan/0011-shunt-manager-Add-flush-method-to-properly-uninstall.patch
@@ -0,0 +1,153 @@
+From bc36530670cbbe2362053f1604f67e481afd336c Mon Sep 17 00:00:00 2001
+From: Tobias Brunner <tobias@strongswan.org>
+Date: Tue, 14 Jul 2015 16:55:36 +0200
+Subject: [PATCH] shunt-manager: Add flush() method to properly uninstall
+ shunts
+
+This will allow us to uninstall shunts before unloading the
+kernel-interface plugins.
+---
+ src/libcharon/sa/shunt_manager.c | 44 ++++++++++++++++++++++++++++++++++++----
+ src/libcharon/sa/shunt_manager.h | 6 ++++++
+ 2 files changed, 46 insertions(+), 4 deletions(-)
+
+diff --git a/src/libcharon/sa/shunt_manager.c b/src/libcharon/sa/shunt_manager.c
+index 2e42e7e..1a98443 100644
+--- a/src/libcharon/sa/shunt_manager.c
++++ b/src/libcharon/sa/shunt_manager.c
+@@ -19,8 +19,11 @@
+ #include <hydra.h>
+ #include <daemon.h>
+ #include <threading/rwlock.h>
++#include <threading/rwlock_condvar.h>
+ #include <collections/linked_list.h>
+
++#define INSTALL_DISABLED ((u_int)~0)
++
+ typedef struct private_shunt_manager_t private_shunt_manager_t;
+
+ /**
+@@ -42,6 +45,16 @@ struct private_shunt_manager_t {
+ * Lock to safely access the list of shunts
+ */
+ rwlock_t *lock;
++
++ /**
++ * Number of threads currently installing shunts, or INSTALL_DISABLED
++ */
++ u_int installing;
++
++ /**
++ * Condvar to signal shunt installation
++ */
++ rwlock_condvar_t *condvar;
+ };
+
+ /**
+@@ -126,6 +139,11 @@ METHOD(shunt_manager_t, install, bool,
+
+ /* check if not already installed */
+ this->lock->write_lock(this->lock);
++ if (this->installing == INSTALL_DISABLED)
++ { /* flush() has been called */
++ this->lock->unlock(this->lock);
++ return FALSE;
++ }
+ enumerator = this->shunts->create_enumerator(this->shunts);
+ while (enumerator->enumerate(enumerator, &child_cfg))
+ {
+@@ -144,17 +162,20 @@ METHOD(shunt_manager_t, install, bool,
+ return TRUE;
+ }
+ this->shunts->insert_last(this->shunts, child->get_ref(child));
++ this->installing++;
+ this->lock->unlock(this->lock);
+
+ success = install_shunt_policy(child);
+
++ this->lock->write_lock(this->lock);
+ if (!success)
+ {
+- this->lock->write_lock(this->lock);
+ this->shunts->remove(this->shunts, child, NULL);
+- this->lock->unlock(this->lock);
+ child->destroy(child);
+ }
++ this->installing--;
++ this->condvar->signal(this->condvar);
++ this->lock->unlock(this->lock);
+ return success;
+ }
+
+@@ -263,18 +284,31 @@ METHOD(shunt_manager_t, create_enumerator, enumerator_t*,
+ (void*)this->lock->unlock, this->lock);
+ }
+
+-METHOD(shunt_manager_t, destroy, void,
++METHOD(shunt_manager_t, flush, void,
+ private_shunt_manager_t *this)
+ {
+ child_cfg_t *child;
+
++ 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)
+ {
+ uninstall_shunt_policy(child);
+ child->destroy(child);
+ }
+- this->shunts->destroy(this->shunts);
++ this->installing = INSTALL_DISABLED;
++ this->lock->unlock(this->lock);
++}
++
++METHOD(shunt_manager_t, destroy, void,
++ private_shunt_manager_t *this)
++{
++ this->shunts->destroy_offset(this->shunts, offsetof(child_cfg_t, destroy));
+ this->lock->destroy(this->lock);
++ this->condvar->destroy(this->condvar);
+ free(this);
+ }
+
+@@ -290,10 +324,12 @@ shunt_manager_t *shunt_manager_create()
+ .install = _install,
+ .uninstall = _uninstall,
+ .create_enumerator = _create_enumerator,
++ .flush = _flush,
+ .destroy = _destroy,
+ },
+ .shunts = linked_list_create(),
+ .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
++ .condvar = rwlock_condvar_create(),
+ );
+
+ return &this->public;
+diff --git a/src/libcharon/sa/shunt_manager.h b/src/libcharon/sa/shunt_manager.h
+index 28a795d..c43f5db 100644
+--- a/src/libcharon/sa/shunt_manager.h
++++ b/src/libcharon/sa/shunt_manager.h
+@@ -1,4 +1,5 @@
+ /*
++ * Copyright (C) 2015 Tobias Brunner
+ * Copyright (C) 2011 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+@@ -56,6 +57,11 @@ struct shunt_manager_t {
+ enumerator_t* (*create_enumerator)(shunt_manager_t *this);
+
+ /**
++ * Clear any installed shunt.
++ */
++ void (*flush)(shunt_manager_t *this);
++
++ /**
+ * Destroy a shunt_manager_t.
+ */
+ void (*destroy)(shunt_manager_t *this);
+--
+2.4.6
+