* but until we untangle the virt driver that's not viable */
if (!driver->privileged)
return;
- networkPreReloadFirewallRules(startup);
+ networkPreReloadFirewallRules(driver, startup);
virNetworkObjListForEach(driver->networks,
networkReloadFirewallRulesHelper,
NULL);
}
}
-void networkPreReloadFirewallRules(bool startup)
+
+static int
+networkHasRunningNetworksHelper(virNetworkObjPtr obj,
+ void *opaque)
+{
+ bool *running = opaque;
+
+ virObjectLock(obj);
+ if (virNetworkObjIsActive(obj))
+ *running = true;
+ virObjectUnlock(obj);
+
+ return 0;
+}
+
+
+static bool
+networkHasRunningNetworks(virNetworkDriverStatePtr driver)
+{
+ bool running = false;
+ virNetworkObjListForEach(driver->networks,
+ networkHasRunningNetworksHelper,
+ &running);
+ return running;
+}
+
+
+void networkPreReloadFirewallRules(virNetworkDriverStatePtr driver, bool startup)
{
- /* We create global rules upfront as we don't want
- * the perf hit of conditionally figuring out whether
- * to create them each time a network is started.
+ /*
+ * If there are any running networks, we need to
+ * create the global rules upfront. This allows us
+ * convert rules created by old libvirt into the new
+ * format.
+ *
+ * If there are not any running networks, then we
+ * must not create rules, because the rules will
+ * cause the conntrack kernel module to be loaded.
+ * This imposes a significant performance hit on
+ * the networking stack. Thus we will only create
+ * rules if a network is later startup.
*
* Any errors here are saved to be reported at time
* of starting the network though as that makes them
* more likely to be seen by a human
*/
+ if (!networkHasRunningNetworks(driver)) {
+ VIR_DEBUG("Delayed global rule setup as no networks are running");
+ return;
+ }
+
ignore_value(virOnce(&createdOnce, networkSetupPrivateChains));
/*
virFirewallPtr fw = NULL;
int ret = -1;
+ if (virOnce(&createdOnce, networkSetupPrivateChains) < 0)
+ return -1;
+
if (errInitV4 &&
(virNetworkDefGetIPByIndex(def, AF_INET, 0) ||
virNetworkDefGetRouteByIndex(def, AF_INET, 0))) {
#include <config.h>
-void networkPreReloadFirewallRules(bool startup ATTRIBUTE_UNUSED)
+void networkPreReloadFirewallRules(virNetworkDriverStatePtr driver ATTRIBUTE_UNUSED,
+ bool startup ATTRIBUTE_UNUSED)
{
}
typedef struct _virNetworkDriverState virNetworkDriverState;
typedef virNetworkDriverState *virNetworkDriverStatePtr;
-void networkPreReloadFirewallRules(bool startup);
+void networkPreReloadFirewallRules(virNetworkDriverStatePtr driver, bool startup);
void networkPostReloadFirewallRules(bool startup);
int networkCheckRouteCollision(virNetworkDefPtr def);
--- /dev/null
+iptables \
+--table filter \
+--list-rules
+iptables \
+--table nat \
+--list-rules
+iptables \
+--table mangle \
+--list-rules
+iptables \
+--table filter \
+--new-chain LIBVIRT_INP
+iptables \
+--table filter \
+--insert INPUT \
+--jump LIBVIRT_INP
+iptables \
+--table filter \
+--new-chain LIBVIRT_OUT
+iptables \
+--table filter \
+--insert OUTPUT \
+--jump LIBVIRT_OUT
+iptables \
+--table filter \
+--new-chain LIBVIRT_FWO
+iptables \
+--table filter \
+--insert FORWARD \
+--jump LIBVIRT_FWO
+iptables \
+--table filter \
+--new-chain LIBVIRT_FWI
+iptables \
+--table filter \
+--insert FORWARD \
+--jump LIBVIRT_FWI
+iptables \
+--table filter \
+--new-chain LIBVIRT_FWX
+iptables \
+--table filter \
+--insert FORWARD \
+--jump LIBVIRT_FWX
+iptables \
+--table nat \
+--new-chain LIBVIRT_PRT
+iptables \
+--table nat \
+--insert POSTROUTING \
+--jump LIBVIRT_PRT
+iptables \
+--table mangle \
+--new-chain LIBVIRT_PRT
+iptables \
+--table mangle \
+--insert POSTROUTING \
+--jump LIBVIRT_PRT
+ip6tables \
+--table filter \
+--list-rules
+ip6tables \
+--table nat \
+--list-rules
+ip6tables \
+--table mangle \
+--list-rules
+ip6tables \
+--table filter \
+--new-chain LIBVIRT_INP
+ip6tables \
+--table filter \
+--insert INPUT \
+--jump LIBVIRT_INP
+ip6tables \
+--table filter \
+--new-chain LIBVIRT_OUT
+ip6tables \
+--table filter \
+--insert OUTPUT \
+--jump LIBVIRT_OUT
+ip6tables \
+--table filter \
+--new-chain LIBVIRT_FWO
+ip6tables \
+--table filter \
+--insert FORWARD \
+--jump LIBVIRT_FWO
+ip6tables \
+--table filter \
+--new-chain LIBVIRT_FWI
+ip6tables \
+--table filter \
+--insert FORWARD \
+--jump LIBVIRT_FWI
+ip6tables \
+--table filter \
+--new-chain LIBVIRT_FWX
+ip6tables \
+--table filter \
+--insert FORWARD \
+--jump LIBVIRT_FWX
+ip6tables \
+--table nat \
+--new-chain LIBVIRT_PRT
+ip6tables \
+--table nat \
+--insert POSTROUTING \
+--jump LIBVIRT_PRT
+ip6tables \
+--table mangle \
+--new-chain LIBVIRT_PRT
+ip6tables \
+--table mangle \
+--insert POSTROUTING \
+--jump LIBVIRT_PRT
#include <config.h>
#include "testutils.h"
+#include "viralloc.h"
#if defined (__linux__)
}
static int testCompareXMLToArgvFiles(const char *xml,
- const char *cmdline)
+ const char *cmdline,
+ const char *baseargs)
{
char *expectargv = NULL;
char *actualargv = NULL;
virBuffer buf = VIR_BUFFER_INITIALIZER;
virNetworkDefPtr def = NULL;
int ret = -1;
+ char *actual;
virCommandSetDryRun(&buf, testCommandDryRun, NULL);
if (virBufferError(&buf))
goto cleanup;
- actualargv = virBufferContentAndReset(&buf);
+ actual = actualargv = virBufferContentAndReset(&buf);
virTestClearCommandPath(actualargv);
virCommandSetDryRun(NULL, NULL, NULL);
- if (virTestCompareToFile(actualargv, cmdline) < 0)
+ /* The first network to be created populates the
+ * libvirt global chains. We must skip args for
+ * that if present
+ */
+ if (STRPREFIX(actual, baseargs))
+ actual += strlen(baseargs);
+
+ if (virTestCompareToFile(actual, cmdline) < 0)
goto cleanup;
ret = 0;
struct testInfo {
const char *name;
+ const char *baseargs;
};
abs_srcdir, info->name, RULESTYPE) < 0)
goto cleanup;
- result = testCompareXMLToArgvFiles(xml, args);
+ result = testCompareXMLToArgvFiles(xml, args, info->baseargs);
cleanup:
VIR_FREE(xml);
mymain(void)
{
int ret = 0;
+ VIR_AUTOFREE(char *)basefile = NULL;
+ VIR_AUTOFREE(char *)baseargs = NULL;
# define DO_TEST(name) \
do { \
- static struct testInfo info = { \
- name, \
+ struct testInfo info = { \
+ name, baseargs, \
}; \
if (virTestRun("Network XML-2-iptables " name, \
testCompareXMLToIPTablesHelper, &info) < 0) \
goto cleanup;
}
+ if (virAsprintf(&basefile, "%s/networkxml2firewalldata/base.args",
+ abs_srcdir) < 0) {
+ ret = -1;
+ goto cleanup;
+ }
+
+ if (virTestLoadFile(basefile, &baseargs) < 0) {
+ ret = -1;
+ goto cleanup;
+ }
+
DO_TEST("nat-default");
DO_TEST("nat-tftp");
DO_TEST("nat-many-ips");