[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Libvir] [patch 5/5] iptables: reload rules on SIGHUP



As suggested by danpb, make libvirt_qemud handle SIGHUP by re-loading
the iptables rules.

Signed-off-by: Mark McLoughlin <markmc redhat com>

Index: libvirt/qemud/iptables.c
===================================================================
--- libvirt.orig/qemud/iptables.c
+++ libvirt/qemud/iptables.c
@@ -36,6 +36,8 @@
 #include <sys/stat.h>
 #include <sys/wait.h>
 
+#include "internal.h"
+
 enum {
     ADD = 0,
     REMOVE
@@ -48,11 +50,18 @@ enum {
 
 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 int
-iptRulesAppend(iptRules *rules,
-               const char *rule)
+static void
+iptRuleFree(iptRule *rule)
 {
-    char **r;
+    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;
+    }
+}
 
-    if (!(r = (char **)realloc(rules->rules, sizeof(char *) * (rules->nrules+1))))
+static int
+iptRulesAppend(iptRules *rules,
+               char *rule,
+               char **argv,
+               int flipflop)
+{
+    iptRule *r;
+
+    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
@@ -480,10 +511,13 @@ iptablesAddRemoveRule(iptRules *rules, i
         (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)
@@ -535,6 +569,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: libvirt/qemud/iptables.h
===================================================================
--- libvirt.orig/qemud/iptables.h
+++ libvirt/qemud/iptables.h
@@ -27,6 +27,8 @@ typedef struct _iptablesContext iptables
 iptablesContext *iptablesContextNew              (void);
 void             iptablesContextFree             (iptablesContext *ctx);
 
+void             iptablesReloadRules             (iptablesContext *ctx);
+
 int              iptablesAddTcpInput             (iptablesContext *ctx,
                                                   const char *iface,
                                                   int port);
Index: libvirt/qemud/qemud.c
===================================================================
--- libvirt.orig/qemud/qemud.c
+++ libvirt/qemud/qemud.c
@@ -88,6 +88,11 @@ static int qemudDispatchSignal(struct qe
     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:

-- 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]