Wed Mar 30 17:25:33 IST 2007 Mark McLoughlin <markmc@redhat.com>

* qemud/iptables.c: As suggested by danpb, make libvirt_qemud
        handle SIGHUP by re-loading the iptables rules.
This commit is contained in:
Mark McLoughlin 2007-03-30 16:25:02 +00:00
parent 812b34fdd8
commit 8ba930c380
4 changed files with 110 additions and 23 deletions

View File

@ -1,3 +1,8 @@
Wed Mar 30 17:25:33 IST 2007 Mark McLoughlin <markmc@redhat.com>
* qemud/iptables.c: As suggested by danpb, make libvirt_qemud
handle SIGHUP by re-loading the iptables rules.
Wed Mar 30 17:24:48 IST 2007 Mark McLoughlin <markmc@redhat.com>
* qemud/iptables.c: Re-factor things a little so that we

View File

@ -36,6 +36,8 @@
#include <sys/stat.h>
#include <sys/wait.h>
#include "internal.h"
enum {
ADD = 0,
REMOVE
@ -46,13 +48,20 @@ enum {
NO_ERRORS
};
typedef struct
{
char *rule;
char **argv;
int flipflop;
} iptRule;
typedef struct
{
char *table;
char *chain;
int nrules;
char **rules;
int nrules;
iptRule *rules;
#ifdef IPTABLES_DIR
@ -73,7 +82,7 @@ struct _iptablesContext
#ifdef IPTABLES_DIR
static int
writeRules(const char *path,
char * const *rules,
const iptRules *rules,
int nrules)
{
char tmp[PATH_MAX];
@ -96,7 +105,7 @@ writeRules(const char *path,
}
for (i = 0; i < nrules; i++) {
if (fputs(rules[i], f) == EOF ||
if (fputs(rules[i].rule, f) == EOF ||
fputc('\n', f) == EOF) {
fclose(f);
if (istmp)
@ -173,19 +182,43 @@ buildPath(const char *table,
}
#endif /* IPTABLES_DIR */
static void
iptRuleFree(iptRule *rule)
{
if (rule->rule)
free(rule->rule);
rule->rule = NULL;
if (rule->argv) {
int i = 0;
while (rule->argv[i])
free(rule->argv[i++]);
free(rule->argv);
rule->argv = NULL;
}
}
static int
iptRulesAppend(iptRules *rules,
const char *rule)
char *rule,
char **argv,
int flipflop)
{
char **r;
iptRule *r;
if (!(r = (char **)realloc(rules->rules, sizeof(char *) * (rules->nrules+1))))
if (!(r = (iptRule *)realloc(rules->rules, sizeof(iptRule) * (rules->nrules+1)))) {
int i = 0;
while (argv[i])
free(argv[i++]);
free(argv);
return ENOMEM;
}
rules->rules = r;
if (!(rules->rules[rules->nrules] = strdup(rule)))
return ENOMEM;
rules->rules[rules->nrules].rule = rule;
rules->rules[rules->nrules].argv = argv;
rules->rules[rules->nrules].flipflop = flipflop;
rules->nrules++;
@ -211,17 +244,17 @@ iptRulesRemove(iptRules *rules,
int i;
for (i = 0; i < rules->nrules; i++)
if (!strcmp(rules->rules[i], strdup(rule)))
if (!strcmp(rules->rules[i].rule, strdup(rule)))
break;
if (i >= rules->nrules)
return EINVAL;
free(rules->rules[i]);
iptRuleFree(&rules->rules[i]);
memmove(&rules->rules[i],
&rules->rules[i+1],
(rules->nrules - i - 1) * sizeof (char *));
(rules->nrules - i - 1) * sizeof (iptRule));
rules->nrules--;
@ -253,16 +286,14 @@ iptRulesFree(iptRules *rules)
}
for (i = 0; i < rules->nrules; i++) {
free(rules->rules[i]);
rules->rules[i] = NULL;
}
rules->nrules = 0;
if (rules->rules) {
for (i = 0; i < rules->nrules; i++)
iptRuleFree(&rules->rules[i]);
free(rules->rules);
rules->rules = NULL;
rules->nrules = 0;
}
#ifdef IPTABLES_DIR
@ -401,7 +432,7 @@ iptablesAddRemoveRule(iptRules *rules, int action, const char *arg, ...)
char **argv;
char *rule = NULL, *p;
const char *s;
int n, rulelen;
int n, rulelen, flipflop;
n = 1 + /* /sbin/iptables */
2 + /* --table foo */
@ -435,6 +466,8 @@ iptablesAddRemoveRule(iptRules *rules, int action, const char *arg, ...)
if (!(argv[n++] = strdup(rules->table)))
goto error;
flipflop = n;
if (!(argv[n++] = strdup(action == ADD ? "--insert" : "--delete")))
goto error;
@ -473,10 +506,13 @@ iptablesAddRemoveRule(iptRules *rules, int action, const char *arg, ...)
(retval = iptablesAddRemoveChain(rules, action)))
goto error;
if (action == ADD)
retval = iptRulesAppend(rules, rule);
else
if (action == ADD) {
retval = iptRulesAppend(rules, rule, argv, flipflop);
rule = NULL;
argv = NULL;
} else {
retval = iptRulesRemove(rules, rule);
}
error:
if (rule)
@ -528,6 +564,45 @@ iptablesContextFree(iptablesContext *ctx)
free(ctx);
}
static void
iptRulesReload(iptRules *rules)
{
int i;
int retval;
for (i = 0; i < rules->nrules; i++) {
iptRule *rule = &rules->rules[i];
char *orig;
orig = rule->argv[rule->flipflop];
rule->argv[rule->flipflop] = (char *) "--delete";
if ((retval = iptablesSpawn(WITH_ERRORS, rule->argv)))
qemudLog(QEMUD_WARN, "Failed to remove iptables rule '%s' from chain '%s' in table '%s': %s",
rule->rule, rules->chain, rules->table, strerror(errno));
rule->argv[rule->flipflop] = orig;
}
if ((retval = iptablesAddRemoveChain(rules, REMOVE)) ||
(retval = iptablesAddRemoveChain(rules, ADD)))
qemudLog(QEMUD_WARN, "Failed to re-create chain '%s' in table '%s': %s",
rules->chain, rules->table, strerror(retval));
for (i = 0; i < rules->nrules; i++)
if ((retval = iptablesSpawn(WITH_ERRORS, rules->rules[i].argv)))
qemudLog(QEMUD_WARN, "Failed to add iptables rule '%s' to chain '%s' in table '%s': %s",
rules->rules[i].rule, rules->chain, rules->table, strerror(retval));
}
void
iptablesReloadRules(iptablesContext *ctx)
{
iptRulesReload(ctx->input_filter);
iptRulesReload(ctx->forward_filter);
iptRulesReload(ctx->nat_postrouting);
}
static int
iptablesInput(iptablesContext *ctx,
const char *iface,

View File

@ -27,6 +27,8 @@ typedef struct _iptablesContext iptablesContext;
iptablesContext *iptablesContextNew (void);
void iptablesContextFree (iptablesContext *ctx);
void iptablesReloadRules (iptablesContext *ctx);
int iptablesAddTcpInput (iptablesContext *ctx,
const char *iface,
int port);

View File

@ -96,6 +96,11 @@ static int qemudDispatchSignal(struct qemud_server *server)
case SIGHUP:
qemudLog(QEMUD_INFO, "Reloading configuration on SIGHUP");
ret = qemudScanConfigs(server);
if (server->iptables) {
qemudLog(QEMUD_INFO, "Reloading iptables rules");
iptablesReloadRules(server->iptables);
}
break;
case SIGINT: