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.
This commit is contained in:
Mark McLoughlin 2008-01-10 13:54:02 +00:00
parent a43ddc075a
commit b9daf6d9dd
3 changed files with 155 additions and 0 deletions

View File

@ -1,3 +1,18 @@
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

View File

@ -204,6 +204,27 @@ 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/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])

View File

@ -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
@ -85,6 +90,107 @@ struct _iptablesContext
};
#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,
@ -183,6 +289,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;
@ -216,6 +327,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;