]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Wed Mar 30 17:25:33 IST 2007 Mark McLoughlin <markmc@redhat.com>
authorMark McLoughlin <markmc@redhat.com>
Fri, 30 Mar 2007 16:25:02 +0000 (16:25 +0000)
committerMark McLoughlin <markmc@redhat.com>
Fri, 30 Mar 2007 16:25:02 +0000 (16:25 +0000)
        * qemud/iptables.c: As suggested by danpb, make libvirt_qemud
        handle SIGHUP by re-loading the iptables rules.

ChangeLog
qemud/iptables.c
qemud/iptables.h
qemud/qemud.c

index e8bbc0a184e3c235d40d12b8bdf30b9df23317cf..22a35385b47c5b05b31958ed31c7ab9a1f197780 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
index 1458b36c59933410f0b2d75d5dba3670e0f39750..f772a8ed3186e726c54f3c460b56da89bd35203e 100644 (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,
index 3b5bb910e12598eb2ca09db1474f34bc81e83f11..9ef5c1e488039ea78fed61ec2fae05974619e7bb 100644 (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);
index fa5f5d840a33eafea2b163330abd841b8f726579..d54cb5a26c86a733174f138401c638872ba2ba82 100644 (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: