From a8f91cd4666a1e37c464d1147e35b2cd6540ad80 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 20 Nov 2018 12:50:05 +0100 Subject: [PATCH 1/3] ha: Improve distribution of pool addresses over segments This is particularly important for higher number of segments, but even with small numbers there is a significant difference. For instance, with 4 segments the fourth segment had no IPs assigned with the old code, no matter how large the pool, because none of the eight bits used for the segment check hashed/mapped to it. --- src/libcharon/plugins/ha/ha_attribute.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/libcharon/plugins/ha/ha_attribute.c b/src/libcharon/plugins/ha/ha_attribute.c index 34d6efc48..224e22362 100644 --- a/src/libcharon/plugins/ha/ha_attribute.c +++ b/src/libcharon/plugins/ha/ha_attribute.c @@ -159,13 +159,13 @@ static pool_t* get_pool(private_ha_attribute_t *this, char *name) } /** - * Check if we are responsible for a bit in our bitmask + * Check if we are responsible for an offset */ -static bool responsible_for(private_ha_attribute_t *this, int bit) +static bool responsible_for(private_ha_attribute_t *this, int offset) { u_int segment; - segment = this->kernel->get_segment_int(this->kernel, bit); + segment = this->kernel->get_segment_int(this->kernel, offset); return this->segments->is_active(this->segments, segment); } @@ -175,7 +175,7 @@ METHOD(attribute_provider_t, acquire_address, host_t*, { enumerator_t *enumerator; pool_t *pool = NULL; - int offset = -1, byte, bit; + int offset = -1, tmp_offset, byte, bit; host_t *address; char *name; @@ -199,10 +199,11 @@ METHOD(attribute_provider_t, acquire_address, host_t*, { for (bit = 0; bit < 8; bit++) { + tmp_offset = byte * 8 + bit; if (!(pool->mask[byte] & 1 << bit) && - responsible_for(this, bit)) + responsible_for(this, tmp_offset)) { - offset = byte * 8 + bit; + offset = tmp_offset; pool->mask[byte] |= 1 << bit; break; } From 16a898f5f75e21917e78ab65c43ec85efcfac5b2 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 20 Nov 2018 16:39:04 +0100 Subject: [PATCH 2/3] ha: Add getter for the number of segments --- src/libcharon/plugins/ha/ha_segments.c | 7 +++++++ src/libcharon/plugins/ha/ha_segments.h | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/src/libcharon/plugins/ha/ha_segments.c b/src/libcharon/plugins/ha/ha_segments.c index 0a407f9ef..153534915 100644 --- a/src/libcharon/plugins/ha/ha_segments.c +++ b/src/libcharon/plugins/ha/ha_segments.c @@ -433,6 +433,12 @@ METHOD(ha_segments_t, is_active, bool, return (this->active & SEGMENTS_BIT(segment)) != 0; } +METHOD(ha_segments_t, count, u_int, + private_ha_segments_t *this) +{ + return this->count; +} + METHOD(ha_segments_t, destroy, void, private_ha_segments_t *this) { @@ -459,6 +465,7 @@ ha_segments_t *ha_segments_create(ha_socket_t *socket, ha_kernel_t *kernel, .deactivate = _deactivate, .handle_status = _handle_status, .is_active = _is_active, + .count = _count, .destroy = _destroy, }, .socket = socket, diff --git a/src/libcharon/plugins/ha/ha_segments.h b/src/libcharon/plugins/ha/ha_segments.h index 10d5812c6..bc96a8d3e 100644 --- a/src/libcharon/plugins/ha/ha_segments.h +++ b/src/libcharon/plugins/ha/ha_segments.h @@ -82,6 +82,13 @@ struct ha_segments_t { */ bool (*is_active)(ha_segments_t *this, u_int segment); + /** + * Return the number of segments + * + * @return number of segments + */ + u_int (*count)(ha_segments_t *this); + /** * Destroy a ha_segments_t. */ From 5dbb826da5eb11f5f5d3380185b082c9e6f2fe01 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 20 Nov 2018 16:40:21 +0100 Subject: [PATCH 3/3] ha: Divide virtual IPs evenly among all segments --- src/libcharon/plugins/ha/ha_attribute.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcharon/plugins/ha/ha_attribute.c b/src/libcharon/plugins/ha/ha_attribute.c index 224e22362..2553fd014 100644 --- a/src/libcharon/plugins/ha/ha_attribute.c +++ b/src/libcharon/plugins/ha/ha_attribute.c @@ -165,7 +165,7 @@ static bool responsible_for(private_ha_attribute_t *this, int offset) { u_int segment; - segment = this->kernel->get_segment_int(this->kernel, offset); + segment = offset % this->segments->count(this->segments) + 1; return this->segments->is_active(this->segments, segment); }