aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Willi <martin@strongswan.org>2009-09-29 16:05:46 +0200
committerMartin Willi <martin@revosec.ch>2010-04-07 13:55:16 +0200
commita05e38854008277751047b3582d6ecbfd286fcf7 (patch)
tree464bf05ef4e2c7e406d2881638038bfbcfb3b8d9
parente262f4e54372dd36f10523392a75b881a7f21d5b (diff)
downloadstrongswan-a05e38854008277751047b3582d6ecbfd286fcf7.tar.bz2
strongswan-a05e38854008277751047b3582d6ecbfd286fcf7.tar.xz
Do not install iptables rules, they should stay active after shutdown
-rw-r--r--src/charon/plugins/ha/ha_kernel.c183
-rw-r--r--src/charon/plugins/ha/ha_kernel.h3
-rw-r--r--src/charon/plugins/ha/ha_plugin.c6
3 files changed, 92 insertions, 100 deletions
diff --git a/src/charon/plugins/ha/ha_kernel.c b/src/charon/plugins/ha/ha_kernel.c
index f04b41784..69e1c9e28 100644
--- a/src/charon/plugins/ha/ha_kernel.c
+++ b/src/charon/plugins/ha/ha_kernel.c
@@ -26,6 +26,8 @@ typedef u_int8_t u8;
#include <sys/stat.h>
#include <fcntl.h>
+#define CLUSTERIP_DIR "/proc/net/ipt_CLUSTERIP"
+
typedef struct private_ha_kernel_t private_ha_kernel_t;
/**
@@ -47,11 +49,6 @@ struct private_ha_kernel_t {
* Total number of ClusterIP segments
*/
u_int count;
-
- /**
- * List of virtual addresses, as host_t*
- */
- linked_list_t *virtuals;
};
/**
@@ -74,38 +71,75 @@ static bool in_segment(private_ha_kernel_t *this, host_t *host, u_int segment)
}
return FALSE;
}
+
/**
- * Activate/Deactivate a segment
+ * Activate/Deactivate a segment for a given clusterip file
*/
-static void activate_deactivate(private_ha_kernel_t *this,
- u_int segment, char op)
+static void enable_disable(private_ha_kernel_t *this, u_int segment,
+ char *file, bool enable)
{
- enumerator_t *enumerator;
- host_t *host;
- char cmd[8], file[256];
+ char cmd[8];
int fd;
- enumerator = this->virtuals->create_enumerator(this->virtuals);
- while (enumerator->enumerate(enumerator, &host))
+ snprintf(cmd, sizeof(cmd), "%c%d\n", enable ? '+' : '-', segment);
+
+ fd = open(file, O_WRONLY);
+ if (fd == -1)
{
- snprintf(file, sizeof(file), "/proc/net/ipt_CLUSTERIP/%H", host);
- snprintf(cmd, sizeof(cmd), "%c%d\n", op, segment);
+ DBG1(DBG_CFG, "opening CLUSTERIP file '%s' failed: %s",
+ file, strerror(errno));
+ return;
+ }
+ if (write(fd, cmd, strlen(cmd) == -1))
+ {
+ DBG1(DBG_CFG, "writing to CLUSTERIP file '%s' failed: %s",
+ file, strerror(errno));
+ }
+ close(fd);
+}
- fd = open(file, O_WRONLY);
- if (fd == -1)
- {
- DBG1(DBG_CFG, "opening CLUSTERIP file '%s' failed: %s",
- file, strerror(errno));
- continue;
- }
- if (write(fd, cmd, strlen(cmd) == -1))
+/**
+ * Get the currenlty active segments in the kernel for a clusterip file
+ */
+static segment_mask_t get_active(private_ha_kernel_t *this, char *file)
+{
+ char buf[256];
+ segment_mask_t mask = 0;
+ ssize_t len;
+ int fd;
+
+ fd = open(file, O_RDONLY);
+ if (fd == -1)
+ {
+ DBG1(DBG_CFG, "opening CLUSTERIP file '%s' failed: %s",
+ file, strerror(errno));
+ return 0;
+ }
+ len = read(fd, buf, sizeof(buf)-1);
+ if (len == -1)
+ {
+ DBG1(DBG_CFG, "reading from CLUSTERIP file '%s' failed: %s",
+ file, strerror(errno));
+ }
+ else
+ {
+ enumerator_t *enumerator;
+ u_int segment;
+ char *token;
+
+ buf[len] = '\0';
+ enumerator = enumerator_create_token(buf, ",", " ");
+ while (enumerator->enumerate(enumerator, &token))
{
- DBG1(DBG_CFG, "writing to CLUSTERIP file '%s' failed: %s",
- file, strerror(errno));
+ segment = atoi(token);
+ if (segment)
+ {
+ mask |= SEGMENTS_BIT(segment);
+ }
}
- close(fd);
+ enumerator->destroy(enumerator);
}
- enumerator->destroy(enumerator);
+ return mask;
}
/**
@@ -113,7 +147,15 @@ static void activate_deactivate(private_ha_kernel_t *this,
*/
static void activate(private_ha_kernel_t *this, u_int segment)
{
- activate_deactivate(this, segment, '+');
+ enumerator_t *enumerator;
+ char *file;
+
+ enumerator = enumerator_create_directory(CLUSTERIP_DIR);
+ while (enumerator->enumerate(enumerator, NULL, &file, NULL))
+ {
+ enable_disable(this, segment, file, TRUE);
+ }
+ enumerator->destroy(enumerator);
}
/**
@@ -121,75 +163,37 @@ static void activate(private_ha_kernel_t *this, u_int segment)
*/
static void deactivate(private_ha_kernel_t *this, u_int segment)
{
- activate_deactivate(this, segment, '-');
-}
-
-/**
- * Mangle IPtable rules for virtual addresses
- */
-static bool mangle_rules(private_ha_kernel_t *this, bool add)
-{
enumerator_t *enumerator;
- host_t *host;
- u_char i, mac = 0x20;
- char *iface, buf[256];
+ char *file;
- enumerator = this->virtuals->create_enumerator(this->virtuals);
- while (enumerator->enumerate(enumerator, &host))
+ enumerator = enumerator_create_directory(CLUSTERIP_DIR);
+ while (enumerator->enumerate(enumerator, NULL, &file, NULL))
{
- iface = charon->kernel_interface->get_interface(
- charon->kernel_interface, host);
- if (!iface)
- {
- DBG1(DBG_CFG, "cluster address %H not installed, ignored", host);
- this->virtuals->remove_at(this->virtuals, enumerator);
- host->destroy(host);
- continue;
- }
- /* iptables insists of a local node specification, enable node 1 */
- snprintf(buf, sizeof(buf),
- "/sbin/iptables -%c INPUT -i %s -d %H -j CLUSTERIP --new "
- "--hashmode sourceip --clustermac 01:00:5e:00:00:%2x "
- "--total-nodes %d --local-node 1",
- add ? 'A' : 'D', iface, host, mac++, this->count);
- free(iface);
- if (system(buf) != 0)
- {
- DBG1(DBG_CFG, "installing CLUSTERIP rule '%s' failed", buf);
- }
+ enable_disable(this, segment, file, FALSE);
}
enumerator->destroy(enumerator);
-
- if (add)
- {
- for (i = 2; i <= this->count; i++)
- {
- activate(this, i);
- }
- }
- return TRUE;
}
/**
- * Parse the list of virtual cluster addresses
+ * Enable all not-yet enabled segments on all clusterip addresses
*/
-static void parse_virtuals(private_ha_kernel_t *this, char *virtual)
+static void activate_all(private_ha_kernel_t *this)
{
enumerator_t *enumerator;
- host_t *host;
+ segment_mask_t active;
+ char *file;
+ int i;
- enumerator = enumerator_create_token(virtual, ",", " ");
- while (enumerator->enumerate(enumerator, &virtual))
+ enumerator = enumerator_create_directory(CLUSTERIP_DIR);
+ while (enumerator->enumerate(enumerator, NULL, &file, NULL))
{
- host = host_create_from_string(virtual, 0);
- if (host)
- {
- this->virtuals->insert_last(this->virtuals, host);
- }
- else
+ active = get_active(this, file);
+ for (i = 1; i <= this->count; i++)
{
- DBG1(DBG_CFG, "virtual cluster address '%s' invalid, ignored",
- virtual);
+ if (!(active & SEGMENTS_BIT(i)))
+ {
+ enable_disable(this, i, file, TRUE);
+ }
}
}
enumerator->destroy(enumerator);
@@ -200,15 +204,13 @@ static void parse_virtuals(private_ha_kernel_t *this, char *virtual)
*/
static void destroy(private_ha_kernel_t *this)
{
- mangle_rules(this, FALSE);
- this->virtuals->destroy_offset(this->virtuals, offsetof(host_t, destroy));
free(this);
}
/**
* See header
*/
-ha_kernel_t *ha_kernel_create(u_int count, char *virtuals)
+ha_kernel_t *ha_kernel_create(u_int count)
{
private_ha_kernel_t *this = malloc_thing(private_ha_kernel_t);
@@ -219,15 +221,8 @@ ha_kernel_t *ha_kernel_create(u_int count, char *virtuals)
this->initval = 0;
this->count = count;
- this->virtuals = linked_list_create();
- parse_virtuals(this, virtuals);
-
- if (!mangle_rules(this, TRUE))
- {
- destroy(this);
- return NULL;
- }
+ activate_all(this);
return &this->public;
}
diff --git a/src/charon/plugins/ha/ha_kernel.h b/src/charon/plugins/ha/ha_kernel.h
index 2e9e18b01..b37cc7667 100644
--- a/src/charon/plugins/ha/ha_kernel.h
+++ b/src/charon/plugins/ha/ha_kernel.h
@@ -64,8 +64,7 @@ struct ha_kernel_t {
*
* @param count total number of segments to use
* @param active bitmask of initially active segments
- * @param virtuals comma separated list of virtual cluster addresses
*/
-ha_kernel_t *ha_kernel_create(u_int count, char *virtuals);
+ha_kernel_t *ha_kernel_create(u_int count);
#endif /* HA_KERNEL_ @}*/
diff --git a/src/charon/plugins/ha/ha_plugin.c b/src/charon/plugins/ha/ha_plugin.c
index 65101f868..fb780cab2 100644
--- a/src/charon/plugins/ha/ha_plugin.c
+++ b/src/charon/plugins/ha/ha_plugin.c
@@ -103,7 +103,7 @@ static void destroy(private_ha_plugin_t *this)
plugin_t *plugin_create()
{
private_ha_plugin_t *this;
- char *local, *remote, *secret, *virtuals;
+ char *local, *remote, *secret;
u_int count;
bool fifo;
@@ -111,8 +111,6 @@ plugin_t *plugin_create()
"charon.plugins.ha.local", NULL);
remote = lib->settings->get_str(lib->settings,
"charon.plugins.ha.remote", NULL);
- virtuals = lib->settings->get_str(lib->settings,
- "charon.plugins.ha.virtuals", "");
secret = lib->settings->get_str(lib->settings,
"charon.plugins.ha.secret", NULL);
fifo = lib->settings->get_bool(lib->settings,
@@ -137,7 +135,7 @@ plugin_t *plugin_create()
free(this);
return NULL;
}
- this->kernel = ha_kernel_create(count, virtuals);
+ this->kernel = ha_kernel_create(count);
if (!this->kernel)
{
this->socket->destroy(this->socket);