diff options
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.patch | 153 |
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 + |