Do not install iptables rules, they should stay active after shutdown
This commit is contained in:
committed by
Martin Willi
parent
e262f4e543
commit
a05e388540
@@ -26,6 +26,8 @@ typedef u_int8_t u8;
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#define CLUSTERIP_DIR "/proc/net/ipt_CLUSTERIP"
|
||||||
|
|
||||||
typedef struct private_ha_kernel_t private_ha_kernel_t;
|
typedef struct private_ha_kernel_t private_ha_kernel_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -47,11 +49,6 @@ struct private_ha_kernel_t {
|
|||||||
* Total number of ClusterIP segments
|
* Total number of ClusterIP segments
|
||||||
*/
|
*/
|
||||||
u_int count;
|
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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Activate/Deactivate a segment
|
* Activate/Deactivate a segment for a given clusterip file
|
||||||
*/
|
*/
|
||||||
static void activate_deactivate(private_ha_kernel_t *this,
|
static void enable_disable(private_ha_kernel_t *this, u_int segment,
|
||||||
u_int segment, char op)
|
char *file, bool enable)
|
||||||
{
|
{
|
||||||
enumerator_t *enumerator;
|
char cmd[8];
|
||||||
host_t *host;
|
|
||||||
char cmd[8], file[256];
|
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
enumerator = this->virtuals->create_enumerator(this->virtuals);
|
snprintf(cmd, sizeof(cmd), "%c%d\n", enable ? '+' : '-', segment);
|
||||||
while (enumerator->enumerate(enumerator, &host))
|
|
||||||
{
|
|
||||||
snprintf(file, sizeof(file), "/proc/net/ipt_CLUSTERIP/%H", host);
|
|
||||||
snprintf(cmd, sizeof(cmd), "%c%d\n", op, segment);
|
|
||||||
|
|
||||||
fd = open(file, O_WRONLY);
|
fd = open(file, O_WRONLY);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
{
|
{
|
||||||
DBG1(DBG_CFG, "opening CLUSTERIP file '%s' failed: %s",
|
DBG1(DBG_CFG, "opening CLUSTERIP file '%s' failed: %s",
|
||||||
file, strerror(errno));
|
file, strerror(errno));
|
||||||
continue;
|
return;
|
||||||
}
|
|
||||||
if (write(fd, cmd, strlen(cmd) == -1))
|
|
||||||
{
|
|
||||||
DBG1(DBG_CFG, "writing to CLUSTERIP file '%s' failed: %s",
|
|
||||||
file, strerror(errno));
|
|
||||||
}
|
|
||||||
close(fd);
|
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
if (write(fd, cmd, strlen(cmd) == -1))
|
||||||
|
{
|
||||||
|
DBG1(DBG_CFG, "writing to CLUSTERIP file '%s' failed: %s",
|
||||||
|
file, strerror(errno));
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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))
|
||||||
|
{
|
||||||
|
segment = atoi(token);
|
||||||
|
if (segment)
|
||||||
|
{
|
||||||
|
mask |= SEGMENTS_BIT(segment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
}
|
||||||
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -113,83 +147,53 @@ static void activate_deactivate(private_ha_kernel_t *this,
|
|||||||
*/
|
*/
|
||||||
static void activate(private_ha_kernel_t *this, u_int segment)
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of ha_kernel_t.deactivate
|
* Implementation of ha_kernel_t.deactivate
|
||||||
*/
|
*/
|
||||||
static void deactivate(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;
|
enumerator_t *enumerator;
|
||||||
host_t *host;
|
char *file;
|
||||||
u_char i, mac = 0x20;
|
|
||||||
char *iface, buf[256];
|
|
||||||
|
|
||||||
enumerator = this->virtuals->create_enumerator(this->virtuals);
|
enumerator = enumerator_create_directory(CLUSTERIP_DIR);
|
||||||
while (enumerator->enumerate(enumerator, &host))
|
while (enumerator->enumerate(enumerator, NULL, &file, NULL))
|
||||||
{
|
{
|
||||||
iface = charon->kernel_interface->get_interface(
|
enable_disable(this, segment, file, FALSE);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
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;
|
enumerator_t *enumerator;
|
||||||
host_t *host;
|
segment_mask_t active;
|
||||||
|
char *file;
|
||||||
|
int i;
|
||||||
|
|
||||||
enumerator = enumerator_create_token(virtual, ",", " ");
|
enumerator = enumerator_create_directory(CLUSTERIP_DIR);
|
||||||
while (enumerator->enumerate(enumerator, &virtual))
|
while (enumerator->enumerate(enumerator, NULL, &file, NULL))
|
||||||
{
|
{
|
||||||
host = host_create_from_string(virtual, 0);
|
active = get_active(this, file);
|
||||||
if (host)
|
for (i = 1; i <= this->count; i++)
|
||||||
{
|
{
|
||||||
this->virtuals->insert_last(this->virtuals, host);
|
if (!(active & SEGMENTS_BIT(i)))
|
||||||
}
|
{
|
||||||
else
|
enable_disable(this, i, file, TRUE);
|
||||||
{
|
}
|
||||||
DBG1(DBG_CFG, "virtual cluster address '%s' invalid, ignored",
|
|
||||||
virtual);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
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)
|
static void destroy(private_ha_kernel_t *this)
|
||||||
{
|
{
|
||||||
mangle_rules(this, FALSE);
|
|
||||||
this->virtuals->destroy_offset(this->virtuals, offsetof(host_t, destroy));
|
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See header
|
* 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);
|
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->initval = 0;
|
||||||
this->count = count;
|
this->count = count;
|
||||||
this->virtuals = linked_list_create();
|
|
||||||
|
|
||||||
parse_virtuals(this, virtuals);
|
activate_all(this);
|
||||||
|
|
||||||
if (!mangle_rules(this, TRUE))
|
|
||||||
{
|
|
||||||
destroy(this);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,8 +64,7 @@ struct ha_kernel_t {
|
|||||||
*
|
*
|
||||||
* @param count total number of segments to use
|
* @param count total number of segments to use
|
||||||
* @param active bitmask of initially active segments
|
* @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_ @}*/
|
#endif /* HA_KERNEL_ @}*/
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ static void destroy(private_ha_plugin_t *this)
|
|||||||
plugin_t *plugin_create()
|
plugin_t *plugin_create()
|
||||||
{
|
{
|
||||||
private_ha_plugin_t *this;
|
private_ha_plugin_t *this;
|
||||||
char *local, *remote, *secret, *virtuals;
|
char *local, *remote, *secret;
|
||||||
u_int count;
|
u_int count;
|
||||||
bool fifo;
|
bool fifo;
|
||||||
|
|
||||||
@@ -111,8 +111,6 @@ plugin_t *plugin_create()
|
|||||||
"charon.plugins.ha.local", NULL);
|
"charon.plugins.ha.local", NULL);
|
||||||
remote = lib->settings->get_str(lib->settings,
|
remote = lib->settings->get_str(lib->settings,
|
||||||
"charon.plugins.ha.remote", NULL);
|
"charon.plugins.ha.remote", NULL);
|
||||||
virtuals = lib->settings->get_str(lib->settings,
|
|
||||||
"charon.plugins.ha.virtuals", "");
|
|
||||||
secret = lib->settings->get_str(lib->settings,
|
secret = lib->settings->get_str(lib->settings,
|
||||||
"charon.plugins.ha.secret", NULL);
|
"charon.plugins.ha.secret", NULL);
|
||||||
fifo = lib->settings->get_bool(lib->settings,
|
fifo = lib->settings->get_bool(lib->settings,
|
||||||
@@ -137,7 +135,7 @@ plugin_t *plugin_create()
|
|||||||
free(this);
|
free(this);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
this->kernel = ha_kernel_create(count, virtuals);
|
this->kernel = ha_kernel_create(count);
|
||||||
if (!this->kernel)
|
if (!this->kernel)
|
||||||
{
|
{
|
||||||
this->socket->destroy(this->socket);
|
this->socket->destroy(this->socket);
|
||||||
|
|||||||
Reference in New Issue
Block a user