ha_sync_tunnel.h ha_sync_tunnel.c \
ha_sync_dispatcher.h ha_sync_dispatcher.c \
ha_sync_segments.h ha_sync_segments.c \
+ ha_sync_kernel.h ha_sync_kernel.c \
ha_sync_ctl.h ha_sync_ctl.c \
ha_sync_ike.h ha_sync_ike.c \
ha_sync_child.h ha_sync_child.c
--- /dev/null
+/*
+ * Copyright (C) 2009 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "ha_sync_kernel.h"
+
+typedef u_int32_t u32;
+typedef u_int8_t u8;
+
+#include <linux/jhash.h>
+
+typedef struct private_ha_sync_kernel_t private_ha_sync_kernel_t;
+
+/**
+ * Private data of an ha_sync_kernel_t object.
+ */
+struct private_ha_sync_kernel_t {
+
+ /**
+ * Public ha_sync_kernel_t interface.
+ */
+ ha_sync_kernel_t public;
+
+ /**
+ * Init value for jhash
+ */
+ u_int initval;
+
+ /**
+ * Total number of ClusterIP segments
+ */
+ u_int segment_count;
+
+ /**
+ * mask of active segments
+ */
+ segment_mask_t active;
+};
+
+/**
+ * Implementation of ha_sync_kernel_t.in_segment
+ */
+static bool in_segment(private_ha_sync_kernel_t *this, host_t *host, u_int segment)
+{
+ if (host->get_family(host) == AF_INET)
+ {
+ unsigned long hash;
+ u_int32_t addr;
+
+ addr = *(u_int32_t*)host->get_address(host).ptr;
+ hash = jhash_1word(ntohl(addr), this->initval);
+
+ if ((((u_int64_t)hash * this->segment_count) >> 32) + 1 == segment)
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/**
+ * Implementation of ha_sync_kernel_t.destroy.
+ */
+static void destroy(private_ha_sync_kernel_t *this)
+{
+ free(this);
+}
+
+/**
+ * See header
+ */
+ha_sync_kernel_t *ha_sync_kernel_create(u_int count, segment_mask_t active,
+ char *external, char *internal)
+{
+ private_ha_sync_kernel_t *this = malloc_thing(private_ha_sync_kernel_t);
+
+ this->public.in_segment = (bool(*)(ha_sync_kernel_t*, host_t *host, u_int segment))in_segment;
+ this->public.destroy = (void(*)(ha_sync_kernel_t*))destroy;
+
+ this->initval = 0;
+ this->segment_count = count;
+
+ return &this->public;
+}
+
--- /dev/null
+/*
+ * Copyright (C) 2009 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup ha_sync_kernel ha_sync_kernel
+ * @{ @ingroup ha_sync
+ */
+
+#ifndef HA_SYNC_KERNEL_H_
+#define HA_SYNC_KERNEL_H_
+
+typedef struct ha_sync_kernel_t ha_sync_kernel_t;
+
+#include "ha_sync_segments.h"
+
+/**
+ * HA sync segment kernel configuration interface.
+ */
+struct ha_sync_kernel_t {
+
+ /**
+ * Check if a host is in a segment.
+ *
+ * @param host host to check
+ * @param segment segment
+ * @return TRUE if host belongs to segment
+ */
+ bool (*in_segment)(ha_sync_kernel_t *this, host_t *host, u_int segment);
+
+ /**
+ * Destroy a ha_sync_kernel_t.
+ */
+ void (*destroy)(ha_sync_kernel_t *this);
+};
+
+/**
+ * Create a ha_sync_kernel instance.
+ *
+ * @param count total number of segments to use
+ * @param active bitmask of initially active segments
+ * @param external external virtual IP the cluster acts as
+ * @param internal internal virtual IP the cluster uses
+ */
+ha_sync_kernel_t *ha_sync_kernel_create(u_int count, segment_mask_t active,
+ char *external, char *internal);
+
+#endif /* HA_SYNC_KERNEL_ @}*/
*/
ha_sync_segments_t *segments;
+ /**
+ * Interface to control segments at kernel level
+ */
+ ha_sync_kernel_t *kernel;
+
/**
* Segment control interface via FIFO
*/
this->child->destroy(this->child);
this->dispatcher->destroy(this->dispatcher);
this->segments->destroy(this->segments);
+ this->kernel->destroy(this->kernel);
this->socket->destroy(this->socket);
DESTROY_IF(this->tunnel);
free(this);
plugin_t *plugin_create()
{
private_ha_sync_plugin_t *this;
- char *local, *remote, *secret;
+ char *local, *remote, *secret, *external, *internal;
segment_mask_t active;
u_int count;
bool fifo;
"charon.plugins.ha_sync.local", NULL);
remote = lib->settings->get_str(lib->settings,
"charon.plugins.ha_sync.remote", NULL);
+ external = lib->settings->get_str(lib->settings,
+ "charon.plugins.ha_sync.external", NULL);
+ internal = lib->settings->get_str(lib->settings,
+ "charon.plugins.ha_sync.internal", NULL);
secret = lib->settings->get_str(lib->settings,
"charon.plugins.ha_sync.secret", NULL);
fifo = lib->settings->get_bool(lib->settings,
DBG1(DBG_CFG, "HA sync config misses local/remote address");
return NULL;
}
+ if (!external || !internal)
+ {
+ DBG1(DBG_CFG, "HA sync config misses external/internal virtual address");
+ return NULL;
+ }
this = malloc_thing(private_ha_sync_plugin_t);
free(this);
return NULL;
}
- this->segments = ha_sync_segments_create(this->socket, count, active);
+ this->kernel = ha_sync_kernel_create(count, active, external, internal);
+ if (!this->kernel)
+ {
+ this->socket->destroy(this->socket);
+ free(this);
+ return NULL;
+ }
+
+ this->segments = ha_sync_segments_create(this->socket, this->kernel,
+ count, active);
if (secret)
{
this->tunnel = ha_sync_tunnel_create(secret, local, remote);
#include <utils/mutex.h>
#include <utils/linked_list.h>
-typedef u_int32_t u32;
-typedef u_int8_t u8;
-
-#include <linux/jhash.h>
-
typedef struct private_ha_sync_segments_t private_ha_sync_segments_t;
/**
ha_sync_socket_t *socket;
/**
- * read/write lock for segment manipulation
+ * Interface to control segments at kernel level
*/
- rwlock_t *lock;
+ ha_sync_kernel_t *kernel;
/**
- * Init value for jhash
+ * read/write lock for segment manipulation
*/
- u_int initval;
+ rwlock_t *lock;
/**
* Total number of ClusterIP segments
segment_mask_t active;
};
-/**
- * Check if a host address is in the CLUSTERIP segment
- */
-static bool in_segment(private_ha_sync_segments_t *this,
- host_t *host, u_int segment)
-{
- if (host->get_family(host) == AF_INET)
- {
- unsigned long hash;
- u_int32_t addr;
-
- addr = *(u_int32_t*)host->get_address(host).ptr;
- hash = jhash_1word(ntohl(addr), this->initval);
-
- if ((((u_int64_t)hash * this->segment_count) >> 32) + 1 == segment)
- {
- return TRUE;
- }
- }
- return FALSE;
-}
-
/**
* Log currently active segments
*/
{
for (i = segment; i < limit; i++)
{
- if (in_segment(this, ike_sa->get_other_host(ike_sa), i))
+ if (this->kernel->in_segment(this->kernel,
+ ike_sa->get_other_host(ike_sa), i))
{
ike_sa->set_state(ike_sa, new);
}
while (enumerator->enumerate(enumerator, &ike_sa))
{
if (ike_sa->get_state(ike_sa) == IKE_ESTABLISHED &&
- in_segment(this, ike_sa->get_other_host(ike_sa), segment))
+ this->kernel->in_segment(this->kernel,
+ ike_sa->get_other_host(ike_sa), segment))
{
id = ike_sa->get_id(ike_sa);
list->insert_last(list, id->clone(id));
* See header
*/
ha_sync_segments_t *ha_sync_segments_create(ha_sync_socket_t *socket,
+ ha_sync_kernel_t *kernel,
u_int count, segment_mask_t active)
{
private_ha_sync_segments_t *this = malloc_thing(private_ha_sync_segments_t);
this->public.destroy = (void(*)(ha_sync_segments_t*))destroy;
this->socket = socket;
+ this->kernel = kernel;
this->lock = rwlock_create(RWLOCK_TYPE_DEFAULT);
- this->initval = 0;
this->active = active;
this->segment_count = count;
#ifndef HA_SYNC_SEGMENTS_H_
#define HA_SYNC_SEGMENTS_H_
-#include "ha_sync_socket.h"
-
#include <daemon.h>
typedef struct ha_sync_segments_t ha_sync_segments_t;
*/
#define SEGMENTS_BIT(segment) (0x01 << (segment - 1))
+#include "ha_sync_socket.h"
+#include "ha_sync_kernel.h"
+
/**
* Segmentation of peers into active and passive.
*/
* Create a ha_sync_segments instance.
*
* @param socket socket to communicate segment (de-)activation
+ * @param kernel interface to control segments at kernel level
* @param count number of segments the cluster uses
* @param active bit mask of initially active segments
* @return segment object
*/
ha_sync_segments_t *ha_sync_segments_create(ha_sync_socket_t *socket,
+ ha_sync_kernel_t *kernel,
u_int count, segment_mask_t active);
#endif /* HA_SYNC_SEGMENTS_ @}*/