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