summaryrefslogtreecommitdiff
path: root/src/libcharon/plugins/ha/ha_kernel.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/plugins/ha/ha_kernel.c')
-rw-r--r--src/libcharon/plugins/ha/ha_kernel.c96
1 files changed, 64 insertions, 32 deletions
diff --git a/src/libcharon/plugins/ha/ha_kernel.c b/src/libcharon/plugins/ha/ha_kernel.c
index 0ad9c22c3..10a63453a 100644
--- a/src/libcharon/plugins/ha/ha_kernel.c
+++ b/src/libcharon/plugins/ha/ha_kernel.c
@@ -52,24 +52,57 @@ struct private_ha_kernel_t {
};
/**
- * Implementation of ha_kernel_t.in_segment
+ * Segmentate a calculated hash
*/
-static bool in_segment(private_ha_kernel_t *this, host_t *host, u_int segment)
+static u_int hash2segment(private_ha_kernel_t *this, u_int64_t hash)
+{
+ return ((hash * this->count) >> 32) + 1;
+}
+
+/**
+ * Get a host as an integer for hashing
+ */
+static u_int32_t host2int(host_t *host)
{
if (host->get_family(host) == AF_INET)
{
- unsigned long hash;
- u_int32_t addr;
+ return *(u_int32_t*)host->get_address(host).ptr;
+ }
+ return 0;
+}
- addr = *(u_int32_t*)host->get_address(host).ptr;
- hash = jhash_1word(ntohl(addr), this->initval);
+METHOD(ha_kernel_t, get_segment, u_int,
+ private_ha_kernel_t *this, host_t *host)
+{
+ unsigned long hash;
+ u_int32_t addr;
- if ((((u_int64_t)hash * this->count) >> 32) + 1 == segment)
- {
- return TRUE;
- }
- }
- return FALSE;
+ addr = host2int(host);
+ hash = jhash_1word(ntohl(addr), this->initval);
+
+ return hash2segment(this, hash);
+}
+
+METHOD(ha_kernel_t, get_segment_spi, u_int,
+ private_ha_kernel_t *this, host_t *host, u_int32_t spi)
+{
+ unsigned long hash;
+ u_int32_t addr;
+
+ addr = host2int(host);
+ hash = jhash_2words(ntohl(addr), ntohl(spi), this->initval);
+
+ return hash2segment(this, hash);
+}
+
+METHOD(ha_kernel_t, get_segment_int, u_int,
+ private_ha_kernel_t *this, int n)
+{
+ unsigned long hash;
+
+ hash = jhash_1word(ntohl(n), this->initval);
+
+ return hash2segment(this, hash);
}
/**
@@ -142,10 +175,8 @@ static segment_mask_t get_active(private_ha_kernel_t *this, char *file)
return mask;
}
-/**
- * Implementation of ha_kernel_t.activate
- */
-static void activate(private_ha_kernel_t *this, u_int segment)
+METHOD(ha_kernel_t, activate, void,
+ private_ha_kernel_t *this, u_int segment)
{
enumerator_t *enumerator;
char *file;
@@ -158,10 +189,8 @@ static void activate(private_ha_kernel_t *this, u_int segment)
enumerator->destroy(enumerator);
}
-/**
- * Implementation of ha_kernel_t.deactivate
- */
-static void deactivate(private_ha_kernel_t *this, u_int segment)
+METHOD(ha_kernel_t, deactivate, void,
+ private_ha_kernel_t *this, u_int segment)
{
enumerator_t *enumerator;
char *file;
@@ -199,10 +228,8 @@ static void disable_all(private_ha_kernel_t *this)
enumerator->destroy(enumerator);
}
-/**
- * Implementation of ha_kernel_t.destroy.
- */
-static void destroy(private_ha_kernel_t *this)
+METHOD(ha_kernel_t, destroy, void,
+ private_ha_kernel_t *this)
{
free(this);
}
@@ -212,15 +239,20 @@ static void destroy(private_ha_kernel_t *this)
*/
ha_kernel_t *ha_kernel_create(u_int count)
{
- private_ha_kernel_t *this = malloc_thing(private_ha_kernel_t);
-
- this->public.in_segment = (bool(*)(ha_kernel_t*, host_t *host, u_int segment))in_segment;
- this->public.activate = (void(*)(ha_kernel_t*, u_int segment))activate;
- this->public.deactivate = (void(*)(ha_kernel_t*, u_int segment))deactivate;
- this->public.destroy = (void(*)(ha_kernel_t*))destroy;
+ private_ha_kernel_t *this;
- this->initval = 0;
- this->count = count;
+ INIT(this,
+ .public = {
+ .get_segment = _get_segment,
+ .get_segment_spi = _get_segment_spi,
+ .get_segment_int = _get_segment_int,
+ .activate = _activate,
+ .deactivate = _deactivate,
+ .destroy = _destroy,
+ },
+ .initval = 0,
+ .count = count,
+ );
disable_all(this);