[patch 7/9] Add support for lokkit

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

 



Add support for integrating our iptables support with Fedora's
iptables configuration using the lokkit --custom-rules command.

Basically, we write out our rules to /var/lib/libvirt/iptables
and run lokkit --custom-rules so that if e.g. iptables is
restarted or the user edits their firewall configuration, then
libvirt's rules get reloaded.

The slightly nasty bit is that rather than running something
like lokkit --remove-custom-rules, we have to grub around
in /etc/sysconfig/system-config-firewall to remove our
rules files.

Signed-off-by: Mark McLoughlin <markmc@xxxxxxxxxx>

Index: libvirt/configure.in
===================================================================
--- libvirt.orig/configure.in	2008-01-04 14:48:49.000000000 +0000
+++ libvirt.orig/configure.in	2008-01-04 14:48:49.000000000 +0000
@@ -204,6 +204,20 @@ if test x"$IPTABLES_DIR" != "x"; then
    AC_DEFINE_UNQUOTED(IPTABLES_DIR, "$IPTABLES_DIR", [directory used for saving iptables chains])
 fi
 
+dnl
+dnl ensure that Fedora's system-config-firewall knows
+dnl about libvirt's iptables rules
+dnl
+AC_ARG_ENABLE(iptables-lokkit,
+              AC_HELP_STRING([--enable-iptables-lokkit=no/yes],
+                             [enable registering libvirt's iptables rules with Fedora's lokkit]),
+                             [],[enable_iptables_lokkit=no])
+if test x"$enable_iptables_lokkit" = x"yes"; then
+   AC_DEFINE(ENABLE_IPTABLES_LOKKIT, [], [whether support for Fedora's lokkit is enabled])
+   AC_PATH_PROG(LOKKIT_PATH, lokkit, /usr/sbin/lokkit)
+   AC_DEFINE_UNQUOTED(LOKKIT_PATH, "$LOKKIT_PATH", [path to lokkit binary])
+fi
+
 AC_PATH_PROG(IPTABLES_PATH, iptables, /sbin/iptables)
 AC_DEFINE_UNQUOTED(IPTABLES_PATH, "$IPTABLES_PATH", [path to iptables binary])
 
Index: libvirt/src/iptables.c
===================================================================
--- libvirt.orig/src/iptables.c	2008-01-04 14:51:29.000000000 +0000
+++ libvirt.orig/src/iptables.c	2008-01-04 14:51:29.000000000 +0000
@@ -48,6 +48,11 @@
 
 #define qemudLog(level, msg...) fprintf(stderr, msg)
 
+#ifdef ENABLE_IPTABLES_LOKKIT
+#undef IPTABLES_DIR
+#define IPTABLES_DIR LOCAL_STATE_DIR "/lib/libvirt/iptables"
+#endif
+
 enum {
     ADD = 0,
     REMOVE
@@ -133,6 +138,108 @@ iptablesSpawn(int errors, char * const *
 }
 
 #ifdef IPTABLES_DIR
+#ifdef ENABLE_IPTABLES_LOKKIT
+static void
+notifyRulesUpdated(const char *table,
+                   const char *path)
+{
+    char arg[PATH_MAX];
+    char *argv[4];
+    int retval;
+
+    snprintf(arg, sizeof(arg), "--custom-rules=ipv4:%s:%s", table, path);
+
+    argv[0] = (char *) LOKKIT_PATH;
+    argv[1] = (char *) "--nostart";
+    argv[2] = arg;
+    argv[3] = NULL;
+
+    if ((retval = iptablesSpawn(WITH_ERRORS, argv)))
+        qemudLog(QEMUD_WARN, "Failed to run '" LOKKIT_PATH " %s' : %s",
+                 arg, strerror(retval));
+}
+
+static int
+stripLine(char *str, int len, const char *line)
+{
+    char *s, *p;
+    int changed;
+
+    changed = 0;
+    s = str;
+
+    while ((p = strchr(s, '\n'))) {
+        if (p == s || strncmp(s, line, p - s) != 0) {
+            s = ++p;
+            continue;
+        }
+
+        ++p;
+        memmove(s, p, len - (p - str) + 1);
+        len -= p - s;
+        changed = 1;
+    }
+
+    if (strcmp(s, line) == 0) {
+        *s = '\0';
+        changed = 1;
+    }
+
+    return changed;
+}
+
+static void
+notifyRulesRemoved(const char *table,
+                   const char *path)
+{
+/* 10 MB limit on config file size as a sanity check */
+#define MAX_FILE_LEN (1024*1024*10)
+
+    char arg[PATH_MAX];
+    char *content;
+    int len;
+    FILE *f = NULL;
+
+    len = virFileReadAll(SYSCONF_DIR "/sysconfig/system-config-firewall",
+                         MAX_FILE_LEN, &content);
+    if (len < 0) {
+        qemudLog(QEMUD_WARN, "Failed to read " SYSCONF_DIR "/sysconfig/system-config-firewall");
+        return;
+    }
+
+    snprintf(arg, sizeof(arg), "--custom-rules=ipv4:%s:%s", table, path);
+
+    if (!stripLine(content, len, arg)) {
+        free(content);
+        return;
+    }
+
+    if (!(f = fopen(SYSCONF_DIR "/sysconfig/system-config-firewall", "w")))
+        goto write_error;
+
+    if (fputs(content, f) == EOF)
+        goto write_error;
+
+    if (fclose(f) == EOF) {
+        f = NULL;
+        goto write_error;
+    }
+
+    free(content);
+
+    return;
+
+ write_error:
+    qemudLog(QEMUD_WARN, "Failed to write to " SYSCONF_DIR "/sysconfig/system-config-firewall : %s",
+             strerror(errno));
+    if (f)
+        fclose(f);
+    free(content);
+
+#undef MAX_FILE_LEN
+}
+#endif /* ENABLE_IPTABLES_LOKKIT */
+
 static int
 writeRules(const char *path,
            const iptRule *rules,
@@ -231,6 +338,11 @@ iptRulesAppend(iptRules *rules,
         if ((err = writeRules(rules->path, rules->rules, rules->nrules)))
             return err;
     }
+
+#ifdef ENABLE_IPTABLES_LOKKIT
+    notifyRulesUpdated(rules->table, rules->path);
+#endif /* ENABLE_IPTABLES_LOKKIT */
+
 #endif /* IPTABLES_DIR */
 
     return 0;
@@ -264,6 +376,14 @@ iptRulesRemove(iptRules *rules,
         if ((err = writeRules(rules->path, rules->rules, rules->nrules)))
             return err;
     }
+
+#ifdef ENABLE_IPTABLES_LOKKIT
+    if (rules->nrules > 0)
+        notifyRulesUpdated(rules->table, rules->path);
+    else
+        notifyRulesRemoved(rules->table, rules->path);
+#endif /* ENABLE_IPTABLES_LOKKIT */
+
 #endif /* IPTABLES_DIR */
 
     return 0;

-- 

--
Libvir-list mailing list
Libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list

[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]