+Thu Jan 10 13:52:05 GMT 2008 Mark McLoughlin <markmc@redhat.com>
+
+ 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.
+
+ * configure.in: Add --enable-iptables-lokkit
+
+ * src/iptables.c: Add support for lokkit
+
Thu Jan 10 13:51:00 GMT 2008 Mark McLoughlin <markmc@redhat.com>
* src/iptables.c: Include the iptables command and chain
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/check],
+ [enable registering libvirt's iptables rules with Fedora's lokkit]),
+ [],[enable_iptables_lokkit=check])
+if test x"$enable_iptables_lokkit" != x"no"; then
+ AC_PATH_PROG(LOKKIT_PATH, lokkit, [], [/usr/sbin:$PATH])
+fi
+
+if test x"$enable_iptables_lokkit" = x"yes" -a x"$LOKKIT_PATH" = x; then
+ AC_MSG_ERROR([Cannot find lokkit and --enable-iptables-lokkit specified])
+fi
+
+if test x"$LOKKIT_PATH" != x; then
+ AC_DEFINE(ENABLE_IPTABLES_LOKKIT, [], [whether support for Fedora's lokkit is enabled])
+ 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])
#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
};
#ifdef IPTABLES_DIR
+#ifdef ENABLE_IPTABLES_LOKKIT
+static void
+notifyRulesUpdated(const char *table,
+ const char *path)
+{
+ char arg[PATH_MAX];
+ char *argv[4];
+
+ 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 (virRun(NULL, argv, NULL) < 0)
+ qemudLog(QEMUD_WARN, "Failed to run '" LOKKIT_PATH " %s' : %s",
+ arg, strerror(errno));
+}
+
+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,
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;
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;