]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Split network driver out into separate files
authorDaniel P. Berrange <berrange@redhat.com>
Fri, 10 Oct 2008 13:57:13 +0000 (13:57 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Fri, 10 Oct 2008 13:57:13 +0000 (13:57 +0000)
ChangeLog
configure.in
src/Makefile.am
src/libvirt.c
src/network_driver.c [new file with mode: 0644]
src/network_driver.h [new file with mode: 0644]
src/qemu_conf.c
src/qemu_conf.h
src/qemu_driver.c

index c30b530b8dd4129d427b3ee7d8f0eb29d2d6be50..c7f128017cd53781ca9dc8bba1997f020108c91b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Fri Oct 10 14:56:00 BST 2008 Daniel P. Berrange <berrange@redhat.com>
+
+       * configure.in: option to enable/disable network driver
+       * src/Makefile.am: Add network_driver.c/.h files
+       * src/libvirt.c: Import network_driver.h file
+       * src/qemu_conf.c, src/qemu-conf.h, src/qemu_driver.c: Remove
+       all network driver support
+       * src/network_driver.c, src/network_driver.h: Add standalone
+       network driver
+
 Fri Oct 10 13:30:00 BST 2008 Daniel P. Berrange <berrange@redhat.com>
 
        * src/xml.c, src/xen_internal.c: Cast some args to unsigned
index 0843f9534c59be4f51ccb600cbd6d4397e0e3411..51bc022238809fccca6b0729477f966e2e29564f 100644 (file)
@@ -643,6 +643,17 @@ AC_SUBST([WITH_XEN])
 AC_SUBST([LIBVIRT_FEATURES])
 
 
+AC_ARG_WITH([network],
+[  --with-network              with virtual network driver (on)],[],[with_network=yes])
+if test "$with_libvirtd" = "no" ; then
+  with_network=no
+fi
+if test "$with_network" = "yes" ; then
+  AC_DEFINE_UNQUOTED([WITH_NETWORK], 1, [whether network driver is enabled])
+fi
+AM_CONDITIONAL([WITH_NETWORK], [test "$with_network" = "yes"])
+
+
 dnl
 dnl Storage driver checks
 dnl
@@ -1070,6 +1081,7 @@ AC_MSG_NOTICE([  OpenVZ: $with_openvz])
 AC_MSG_NOTICE([     LXC: $with_lxc])
 AC_MSG_NOTICE([    Test: $with_test])
 AC_MSG_NOTICE([  Remote: $with_remote])
+AC_MSG_NOTICE([ Network: $with_network])
 AC_MSG_NOTICE([Libvirtd: $with_libvirtd])
 AC_MSG_NOTICE([])
 AC_MSG_NOTICE([Storage Drivers])
index 9a00e36173fbcb54b23582ba0a2e6e40e5b8f56c..7d52b54bc787b8bf0ba7090b6c41c17e0916efe0 100644 (file)
@@ -104,11 +104,12 @@ OPENVZ_DRIVER_SOURCES =                                           \
                openvz_conf.c openvz_conf.h                     \
                openvz_driver.c openvz_driver.h
 
-# XXX network driver should be split out of this
 QEMU_DRIVER_SOURCES =                                          \
                qemu_conf.c qemu_conf.h                         \
                qemu_driver.c qemu_driver.h
 
+NETWORK_DRIVER_SOURCES =                                       \
+               network_driver.h network_driver.c
 
 # And finally storage backend specific impls
 STORAGE_DRIVER_SOURCES =                                       \
@@ -165,9 +166,11 @@ if WITH_OPENVZ
 libvirt_la_SOURCES += $(OPENVZ_DRIVER_SOURCES)
 endif
 
-
 # Drivers usable inside daemon context
 if WITH_LIBVIRTD
+if WITH_NETWORK
+libvirt_la_SOURCES += $(NETWORK_DRIVER_SOURCES)
+endif
 libvirt_la_SOURCES += $(STORAGE_DRIVER_SOURCES)
 libvirt_la_SOURCES += $(STORAGE_DRIVER_FS_SOURCES)
 
@@ -200,6 +203,7 @@ EXTRA_DIST +=                                                       \
                $(QEMU_DRIVER_SOURCES)                          \
                $(LXC_DRIVER_SOURCES)                           \
                $(OPENVZ_DRIVER_SOURCES)                        \
+               $(NETWORK_DRIVER_SOURCES)                       \
                $(STORAGE_DRIVER_SOURCES)                       \
                $(STORAGE_DRIVER_FS_SOURCES)                    \
                $(STORAGE_DRIVER_LVM_SOURCES)                   \
index 10b577d5603ee55e88b14e8dcd92842fbebd49a7..fd6422d682dbcf54968cbad38be613ef0bd1e631 100644 (file)
@@ -57,6 +57,9 @@
 #include "lxc_driver.h"
 #endif
 #include "storage_driver.h"
+#ifdef WITH_NETWORK
+#include "network_driver.h"
+#endif
 
 /*
  * TODO:
@@ -292,6 +295,9 @@ virInitialize(void)
 #endif
 #ifdef WITH_LXC
     if (lxcRegister() == -1) return -1;
+#endif
+#ifdef WITH_NETWORK
+    if (networkRegister() == -1) return -1;
 #endif
     if (storageRegister() == -1) return -1;
 #ifdef WITH_REMOTE
diff --git a/src/network_driver.c b/src/network_driver.c
new file mode 100644 (file)
index 0000000..72860b1
--- /dev/null
@@ -0,0 +1,1168 @@
+/*
+ * driver.c: core driver methods for managing qemu guests
+ *
+ * Copyright (C) 2006, 2007, 2008 Red Hat, Inc.
+ * Copyright (C) 2006 Daniel P. Berrange
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ * Author: Daniel P. Berrange <berrange@redhat.com>
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/poll.h>
+#include <dirent.h>
+#include <limits.h>
+#include <string.h>
+#include <stdio.h>
+#include <strings.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/utsname.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <paths.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <sys/wait.h>
+#include <sys/ioctl.h>
+
+#include "network_driver.h"
+#include "network_conf.h"
+#include "driver.h"
+#include "c-ctype.h"
+#include "event.h"
+#include "buf.h"
+#include "util.h"
+#include "memory.h"
+#include "uuid.h"
+#include "iptables.h"
+#include "bridge.h"
+
+/* Main driver state */
+struct network_driver {
+    virNetworkObjPtr networks;
+
+    iptablesContext *iptables;
+    brControl *brctl;
+    char *networkConfigDir;
+    char *networkAutostartDir;
+    char *logDir;
+};
+
+static int networkShutdown(void);
+
+/* networkDebug statements should be changed to use this macro instead. */
+
+#define networkLog(level, msg...) fprintf(stderr, msg)
+
+#define networkReportError(conn, dom, net, code, fmt...)                \
+    __virReportErrorHelper(conn, VIR_FROM_QEMU, code, __FILE__,         \
+                           __FUNCTION__, __LINE__, fmt)
+
+
+static int networkStartNetworkDaemon(virConnectPtr conn,
+                                   struct network_driver *driver,
+                                   virNetworkObjPtr network);
+
+static int networkShutdownNetworkDaemon(virConnectPtr conn,
+                                      struct network_driver *driver,
+                                      virNetworkObjPtr network);
+
+static struct network_driver *driverState = NULL;
+
+
+static
+void networkAutostartConfigs(struct network_driver *driver) {
+    virNetworkObjPtr network;
+
+    network = driver->networks;
+    while (network != NULL) {
+        virNetworkObjPtr next = network->next;
+
+        if (network->autostart &&
+            !virNetworkIsActive(network) &&
+            networkStartNetworkDaemon(NULL, driver, network) < 0) {
+            virErrorPtr err = virGetLastError();
+            networkLog(NETWORK_ERR, _("Failed to autostart network '%s': %s\n"),
+                     network->def->name, err->message);
+        }
+
+        network = next;
+    }
+}
+
+/**
+ * networkStartup:
+ *
+ * Initialization function for the QEmu daemon
+ */
+static int
+networkStartup(void) {
+    uid_t uid = geteuid();
+    struct passwd *pw;
+    char *base = NULL;
+
+    if (VIR_ALLOC(driverState) < 0)
+        return -1;
+
+    if (!uid) {
+        if (asprintf(&driverState->logDir,
+                     "%s/log/libvirt/qemu", LOCAL_STATE_DIR) == -1)
+            goto out_of_memory;
+
+        if ((base = strdup (SYSCONF_DIR "/libvirt")) == NULL)
+            goto out_of_memory;
+    } else {
+        if (!(pw = getpwuid(uid))) {
+            networkLog(NETWORK_ERR, _("Failed to find user record for uid '%d': %s\n"),
+                     uid, strerror(errno));
+            goto out_of_memory;
+        }
+
+        if (asprintf(&driverState->logDir,
+                     "%s/.libvirt/qemu/log", pw->pw_dir) == -1)
+            goto out_of_memory;
+
+        if (asprintf (&base, "%s/.libvirt", pw->pw_dir) == -1) {
+            networkLog (NETWORK_ERR,
+                      "%s", _("out of memory in asprintf\n"));
+            goto out_of_memory;
+        }
+    }
+
+    /* Configuration paths are either ~/.libvirt/qemu/... (session) or
+     * /etc/libvirt/qemu/... (system).
+     */
+    if (asprintf (&driverState->networkConfigDir, "%s/qemu/networks", base) == -1)
+        goto out_of_memory;
+
+    if (asprintf (&driverState->networkAutostartDir, "%s/qemu/networks/autostart",
+                  base) == -1)
+        goto out_of_memory;
+
+    VIR_FREE(base);
+
+    if (virNetworkLoadAllConfigs(NULL,
+                                 &driverState->networks,
+                                 driverState->networkConfigDir,
+                                 driverState->networkAutostartDir) < 0) {
+        networkShutdown();
+        return -1;
+    }
+    networkAutostartConfigs(driverState);
+
+    return 0;
+
+ out_of_memory:
+    networkLog (NETWORK_ERR,
+              "%s", _("networkStartup: out of memory\n"));
+    VIR_FREE(base);
+    VIR_FREE(driverState);
+    return -1;
+}
+
+/**
+ * networkReload:
+ *
+ * Function to restart the QEmu daemon, it will recheck the configuration
+ * files and update its state and the networking
+ */
+static int
+networkReload(void) {
+    virNetworkLoadAllConfigs(NULL,
+                             &driverState->networks,
+                             driverState->networkConfigDir,
+                             driverState->networkAutostartDir);
+
+     if (driverState->iptables) {
+        networkLog(NETWORK_INFO,
+                 "%s", _("Reloading iptables rules\n"));
+        iptablesReloadRules(driverState->iptables);
+    }
+
+    networkAutostartConfigs(driverState);
+
+    return 0;
+}
+
+/**
+ * networkActive:
+ *
+ * Checks if the QEmu daemon is active, i.e. has an active domain or
+ * an active network
+ *
+ * Returns 1 if active, 0 otherwise
+ */
+static int
+networkActive(void) {
+    virNetworkObjPtr net = driverState->networks;
+
+    while (net) {
+        if (virNetworkIsActive(net))
+            return 1;
+        net = net->next;
+    }
+
+    /* Otherwise we're happy to deal with a shutdown */
+    return 0;
+}
+
+/**
+ * networkShutdown:
+ *
+ * Shutdown the QEmu daemon, it will stop all active domains and networks
+ */
+static int
+networkShutdown(void) {
+    virNetworkObjPtr network;
+
+    if (!driverState)
+        return -1;
+
+    /* shutdown active networks */
+    network = driverState->networks;
+    while (network) {
+        virNetworkObjPtr next = network->next;
+        if (virNetworkIsActive(network))
+            networkShutdownNetworkDaemon(NULL, driverState, network);
+        network = next;
+    }
+
+    /* free inactive networks */
+    network = driverState->networks;
+    while (network) {
+        virNetworkObjPtr next = network->next;
+        virNetworkObjFree(network);
+        network = next;
+    }
+    driverState->networks = NULL;
+
+    VIR_FREE(driverState->logDir);
+    VIR_FREE(driverState->networkConfigDir);
+    VIR_FREE(driverState->networkAutostartDir);
+
+    if (driverState->brctl)
+        brShutdown(driverState->brctl);
+    if (driverState->iptables)
+        iptablesContextFree(driverState->iptables);
+
+    VIR_FREE(driverState);
+
+    return 0;
+}
+
+
+static int
+networkBuildDnsmasqArgv(virConnectPtr conn,
+                      virNetworkObjPtr network,
+                      const char ***argv) {
+    int i, len, r;
+    char buf[PATH_MAX];
+
+    len =
+        1 + /* dnsmasq */
+        1 + /* --keep-in-foreground */
+        1 + /* --strict-order */
+        1 + /* --bind-interfaces */
+        (network->def->domain?2:0) + /* --domain name */
+        2 + /* --pid-file "" */
+        2 + /* --conf-file "" */
+        /*2 + *//* --interface virbr0 */
+        2 + /* --except-interface lo */
+        2 + /* --listen-address 10.0.0.1 */
+        1 + /* --dhcp-leasefile=path */
+        (2 * network->def->nranges) + /* --dhcp-range 10.0.0.2,10.0.0.254 */
+        /*  --dhcp-host 01:23:45:67:89:0a,hostname,10.0.0.3 */
+        (2 * network->def->nhosts) +
+        1;  /* NULL */
+
+    if (VIR_ALLOC_N(*argv, len) < 0)
+        goto no_memory;
+
+#define APPEND_ARG(v, n, s) do {     \
+        if (!((v)[(n)] = strdup(s))) \
+            goto no_memory;          \
+    } while (0)
+
+    i = 0;
+
+    APPEND_ARG(*argv, i++, DNSMASQ);
+
+    APPEND_ARG(*argv, i++, "--keep-in-foreground");
+    /*
+     * Needed to ensure dnsmasq uses same algorithm for processing
+     * multiple namedriver entries in /etc/resolv.conf as GLibC.
+     */
+    APPEND_ARG(*argv, i++, "--strict-order");
+    APPEND_ARG(*argv, i++, "--bind-interfaces");
+
+    if (network->def->domain) {
+       APPEND_ARG(*argv, i++, "--domain");
+       APPEND_ARG(*argv, i++, network->def->domain);
+    }
+
+    APPEND_ARG(*argv, i++, "--pid-file");
+    APPEND_ARG(*argv, i++, "");
+
+    APPEND_ARG(*argv, i++, "--conf-file");
+    APPEND_ARG(*argv, i++, "");
+
+    /*
+     * XXX does not actually work, due to some kind of
+     * race condition setting up ipv6 addresses on the
+     * interface. A sleep(10) makes it work, but that's
+     * clearly not practical
+     *
+     * APPEND_ARG(*argv, i++, "--interface");
+     * APPEND_ARG(*argv, i++, network->def->bridge);
+     */
+    APPEND_ARG(*argv, i++, "--listen-address");
+    APPEND_ARG(*argv, i++, network->def->ipAddress);
+
+    APPEND_ARG(*argv, i++, "--except-interface");
+    APPEND_ARG(*argv, i++, "lo");
+
+    /*
+     * NB, dnsmasq command line arg bug means we need to
+     * use a single arg '--dhcp-leasefile=path' rather than
+     * two separate args in '--dhcp-leasefile path' style
+     */
+    snprintf(buf, sizeof(buf), "--dhcp-leasefile=%s/lib/libvirt/dhcp-%s.leases",
+             LOCAL_STATE_DIR, network->def->name);
+    APPEND_ARG(*argv, i++, buf);
+
+    for (r = 0 ; r < network->def->nranges ; r++) {
+        snprintf(buf, sizeof(buf), "%s,%s",
+                 network->def->ranges[r].start,
+                 network->def->ranges[r].end);
+
+        APPEND_ARG(*argv, i++, "--dhcp-range");
+        APPEND_ARG(*argv, i++, buf);
+    }
+
+    for (r = 0 ; r < network->def->nhosts ; r++) {
+        virNetworkDHCPHostDefPtr host = &(network->def->hosts[r]);
+        if ((host->mac) && (host->name)) {
+            snprintf(buf, sizeof(buf), "%s,%s,%s",
+                     host->mac, host->name, host->ip);
+        } else if (host->mac) {
+            snprintf(buf, sizeof(buf), "%s,%s",
+                     host->mac, host->ip);
+        } else if (host->name) {
+            snprintf(buf, sizeof(buf), "%s,%s",
+                     host->name, host->ip);
+        } else
+            continue;
+
+        APPEND_ARG(*argv, i++, "--dhcp-host");
+        APPEND_ARG(*argv, i++, buf);
+    }
+
+#undef APPEND_ARG
+
+    return 0;
+
+ no_memory:
+    if (argv) {
+        for (i = 0; (*argv)[i]; i++)
+            VIR_FREE((*argv)[i]);
+        VIR_FREE(*argv);
+    }
+    networkReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
+                     "%s", _("failed to allocate space for dnsmasq argv"));
+    return -1;
+}
+
+
+static int
+dhcpStartDhcpDaemon(virConnectPtr conn,
+                    virNetworkObjPtr network)
+{
+    const char **argv;
+    int ret, i;
+
+    if (network->def->ipAddress == NULL) {
+        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         "%s", _("cannot start dhcp daemon without IP address for server"));
+        return -1;
+    }
+
+    argv = NULL;
+    if (networkBuildDnsmasqArgv(conn, network, &argv) < 0)
+        return -1;
+
+    ret = virExec(conn, argv, NULL, NULL,
+                  &network->dnsmasqPid, -1, NULL, NULL, VIR_EXEC_NONBLOCK);
+
+    for (i = 0; argv[i]; i++)
+        VIR_FREE(argv[i]);
+    VIR_FREE(argv);
+
+    return ret;
+}
+
+static int
+networkAddMasqueradingIptablesRules(virConnectPtr conn,
+                      struct network_driver *driver,
+                      virNetworkObjPtr network) {
+    int err;
+    /* allow forwarding packets from the bridge interface */
+    if ((err = iptablesAddForwardAllowOut(driver->iptables,
+                                          network->def->network,
+                                          network->def->bridge,
+                                          network->def->forwardDev))) {
+        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("failed to add iptables rule to allow forwarding from '%s' : %s\n"),
+                         network->def->bridge, strerror(err));
+        goto masqerr1;
+    }
+
+    /* allow forwarding packets to the bridge interface if they are part of an existing connection */
+    if ((err = iptablesAddForwardAllowRelatedIn(driver->iptables,
+                                         network->def->network,
+                                         network->def->bridge,
+                                         network->def->forwardDev))) {
+        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("failed to add iptables rule to allow forwarding to '%s' : %s\n"),
+                         network->def->bridge, strerror(err));
+        goto masqerr2;
+    }
+
+    /* enable masquerading */
+    if ((err = iptablesAddForwardMasquerade(driver->iptables,
+                                            network->def->network,
+                                            network->def->forwardDev))) {
+        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("failed to add iptables rule to enable masquerading : %s\n"),
+                         strerror(err));
+        goto masqerr3;
+    }
+
+    return 1;
+
+ masqerr3:
+    iptablesRemoveForwardAllowRelatedIn(driver->iptables,
+                                 network->def->network,
+                                 network->def->bridge,
+                                 network->def->forwardDev);
+ masqerr2:
+    iptablesRemoveForwardAllowOut(driver->iptables,
+                                  network->def->network,
+                                  network->def->bridge,
+                                  network->def->forwardDev);
+ masqerr1:
+    return 0;
+}
+
+static int
+networkAddRoutingIptablesRules(virConnectPtr conn,
+                      struct network_driver *driver,
+                      virNetworkObjPtr network) {
+    int err;
+    /* allow routing packets from the bridge interface */
+    if ((err = iptablesAddForwardAllowOut(driver->iptables,
+                                          network->def->network,
+                                          network->def->bridge,
+                                          network->def->forwardDev))) {
+        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("failed to add iptables rule to allow routing from '%s' : %s\n"),
+                         network->def->bridge, strerror(err));
+        goto routeerr1;
+    }
+
+    /* allow routing packets to the bridge interface */
+    if ((err = iptablesAddForwardAllowIn(driver->iptables,
+                                         network->def->network,
+                                         network->def->bridge,
+                                         network->def->forwardDev))) {
+        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("failed to add iptables rule to allow routing to '%s' : %s\n"),
+                         network->def->bridge, strerror(err));
+        goto routeerr2;
+    }
+
+    return 1;
+
+
+ routeerr2:
+    iptablesRemoveForwardAllowOut(driver->iptables,
+                                  network->def->network,
+                                  network->def->bridge,
+                                  network->def->forwardDev);
+ routeerr1:
+    return 0;
+}
+
+static int
+networkAddIptablesRules(virConnectPtr conn,
+                      struct network_driver *driver,
+                      virNetworkObjPtr network) {
+    int err;
+
+    if (!driver->iptables && !(driver->iptables = iptablesContextNew())) {
+        networkReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
+                     "%s", _("failed to allocate space for IP tables support"));
+        return 0;
+    }
+
+
+    /* allow DHCP requests through to dnsmasq */
+    if ((err = iptablesAddTcpInput(driver->iptables, network->def->bridge, 67))) {
+        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("failed to add iptables rule to allow DHCP requests from '%s' : %s"),
+                         network->def->bridge, strerror(err));
+        goto err1;
+    }
+
+    if ((err = iptablesAddUdpInput(driver->iptables, network->def->bridge, 67))) {
+        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("failed to add iptables rule to allow DHCP requests from '%s' : %s"),
+                         network->def->bridge, strerror(err));
+        goto err2;
+    }
+
+    /* allow DNS requests through to dnsmasq */
+    if ((err = iptablesAddTcpInput(driver->iptables, network->def->bridge, 53))) {
+        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("failed to add iptables rule to allow DNS requests from '%s' : %s"),
+                         network->def->bridge, strerror(err));
+        goto err3;
+    }
+
+    if ((err = iptablesAddUdpInput(driver->iptables, network->def->bridge, 53))) {
+        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("failed to add iptables rule to allow DNS requests from '%s' : %s"),
+                         network->def->bridge, strerror(err));
+        goto err4;
+    }
+
+
+    /* Catch all rules to block forwarding to/from bridges */
+
+    if ((err = iptablesAddForwardRejectOut(driver->iptables, network->def->bridge))) {
+        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("failed to add iptables rule to block outbound traffic from '%s' : %s"),
+                         network->def->bridge, strerror(err));
+        goto err5;
+    }
+
+    if ((err = iptablesAddForwardRejectIn(driver->iptables, network->def->bridge))) {
+        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("failed to add iptables rule to block inbound traffic to '%s' : %s"),
+                         network->def->bridge, strerror(err));
+        goto err6;
+    }
+
+    /* Allow traffic between guests on the same bridge */
+    if ((err = iptablesAddForwardAllowCross(driver->iptables, network->def->bridge))) {
+        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("failed to add iptables rule to allow cross bridge traffic on '%s' : %s"),
+                         network->def->bridge, strerror(err));
+        goto err7;
+    }
+
+
+    /* If masquerading is enabled, set up the rules*/
+    if (network->def->forwardType == VIR_NETWORK_FORWARD_NAT &&
+        !networkAddMasqueradingIptablesRules(conn, driver, network))
+        goto err8;
+    /* else if routing is enabled, set up the rules*/
+    else if (network->def->forwardType == VIR_NETWORK_FORWARD_ROUTE &&
+             !networkAddRoutingIptablesRules(conn, driver, network))
+        goto err8;
+
+    iptablesSaveRules(driver->iptables);
+
+    return 1;
+
+ err8:
+    iptablesRemoveForwardAllowCross(driver->iptables,
+                                    network->def->bridge);
+ err7:
+    iptablesRemoveForwardRejectIn(driver->iptables,
+                                  network->def->bridge);
+ err6:
+    iptablesRemoveForwardRejectOut(driver->iptables,
+                                   network->def->bridge);
+ err5:
+    iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 53);
+ err4:
+    iptablesRemoveTcpInput(driver->iptables, network->def->bridge, 53);
+ err3:
+    iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 67);
+ err2:
+    iptablesRemoveTcpInput(driver->iptables, network->def->bridge, 67);
+ err1:
+    return 0;
+}
+
+static void
+networkRemoveIptablesRules(struct network_driver *driver,
+                         virNetworkObjPtr network) {
+    if (network->def->forwardType != VIR_NETWORK_FORWARD_NONE) {
+        iptablesRemoveForwardMasquerade(driver->iptables,
+                                        network->def->network,
+                                        network->def->forwardDev);
+
+        if (network->def->forwardType == VIR_NETWORK_FORWARD_NAT)
+            iptablesRemoveForwardAllowRelatedIn(driver->iptables,
+                                                network->def->network,
+                                                network->def->bridge,
+                                                network->def->forwardDev);
+        else if (network->def->forwardType == VIR_NETWORK_FORWARD_ROUTE)
+            iptablesRemoveForwardAllowIn(driver->iptables,
+                                         network->def->network,
+                                         network->def->bridge,
+                                         network->def->forwardDev);
+
+        iptablesRemoveForwardAllowOut(driver->iptables,
+                                      network->def->network,
+                                      network->def->bridge,
+                                      network->def->forwardDev);
+    }
+    iptablesRemoveForwardAllowCross(driver->iptables, network->def->bridge);
+    iptablesRemoveForwardRejectIn(driver->iptables, network->def->bridge);
+    iptablesRemoveForwardRejectOut(driver->iptables, network->def->bridge);
+    iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 53);
+    iptablesRemoveTcpInput(driver->iptables, network->def->bridge, 53);
+    iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 67);
+    iptablesRemoveTcpInput(driver->iptables, network->def->bridge, 67);
+    iptablesSaveRules(driver->iptables);
+}
+
+static int
+networkEnableIpForwarding(void)
+{
+#define PROC_IP_FORWARD "/proc/sys/net/ipv4/ip_forward"
+
+    int fd, ret;
+
+    if ((fd = open(PROC_IP_FORWARD, O_WRONLY|O_TRUNC)) == -1)
+        return 0;
+
+    if (safewrite(fd, "1\n", 2) < 0)
+        ret = 0;
+
+    close (fd);
+
+    return 1;
+
+#undef PROC_IP_FORWARD
+}
+
+static int networkStartNetworkDaemon(virConnectPtr conn,
+                                   struct network_driver *driver,
+                                   virNetworkObjPtr network) {
+    int err;
+
+    if (virNetworkIsActive(network)) {
+        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         "%s", _("network is already active"));
+        return -1;
+    }
+
+    if (!driver->brctl && (err = brInit(&driver->brctl))) {
+        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("cannot initialize bridge support: %s"), strerror(err));
+        return -1;
+    }
+
+    if ((err = brAddBridge(driver->brctl, &network->def->bridge))) {
+        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("cannot create bridge '%s' : %s"),
+                         network->def->bridge, strerror(err));
+        return -1;
+    }
+
+
+    if (brSetForwardDelay(driver->brctl, network->def->bridge, network->def->delay) < 0)
+        goto err_delbr;
+
+    if (brSetEnableSTP(driver->brctl, network->def->bridge, network->def->stp ? 1 : 0) < 0)
+        goto err_delbr;
+
+    if (network->def->ipAddress &&
+        (err = brSetInetAddress(driver->brctl, network->def->bridge, network->def->ipAddress))) {
+        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("cannot set IP address on bridge '%s' to '%s' : %s"),
+                         network->def->bridge, network->def->ipAddress, strerror(err));
+        goto err_delbr;
+    }
+
+    if (network->def->netmask &&
+        (err = brSetInetNetmask(driver->brctl, network->def->bridge, network->def->netmask))) {
+        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("cannot set netmask on bridge '%s' to '%s' : %s"),
+                         network->def->bridge, network->def->netmask, strerror(err));
+        goto err_delbr;
+    }
+
+    if (network->def->ipAddress &&
+        (err = brSetInterfaceUp(driver->brctl, network->def->bridge, 1))) {
+        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("failed to bring the bridge '%s' up : %s"),
+                         network->def->bridge, strerror(err));
+        goto err_delbr;
+    }
+
+    if (!networkAddIptablesRules(conn, driver, network))
+        goto err_delbr1;
+
+    if (network->def->forwardType != VIR_NETWORK_FORWARD_NONE &&
+        !networkEnableIpForwarding()) {
+        networkReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                         _("failed to enable IP forwarding : %s"), strerror(err));
+        goto err_delbr2;
+    }
+
+    if (network->def->nranges &&
+        dhcpStartDhcpDaemon(conn, network) < 0)
+        goto err_delbr2;
+
+    network->active = 1;
+
+    return 0;
+
+ err_delbr2:
+    networkRemoveIptablesRules(driver, network);
+
+ err_delbr1:
+    if (network->def->ipAddress &&
+        (err = brSetInterfaceUp(driver->brctl, network->def->bridge, 0))) {
+        networkLog(NETWORK_WARN, _("Failed to bring down bridge '%s' : %s\n"),
+                 network->def->bridge, strerror(err));
+    }
+
+ err_delbr:
+    if ((err = brDeleteBridge(driver->brctl, network->def->bridge))) {
+        networkLog(NETWORK_WARN, _("Failed to delete bridge '%s' : %s\n"),
+                 network->def->bridge, strerror(err));
+    }
+
+    return -1;
+}
+
+
+static int networkShutdownNetworkDaemon(virConnectPtr conn ATTRIBUTE_UNUSED,
+                                      struct network_driver *driver,
+                                      virNetworkObjPtr network) {
+    int err;
+
+    networkLog(NETWORK_INFO, _("Shutting down network '%s'\n"), network->def->name);
+
+    if (!virNetworkIsActive(network))
+        return 0;
+
+    if (network->dnsmasqPid > 0)
+        kill(network->dnsmasqPid, SIGTERM);
+
+    networkRemoveIptablesRules(driver, network);
+
+    if (network->def->ipAddress &&
+        (err = brSetInterfaceUp(driver->brctl, network->def->bridge, 0))) {
+        networkLog(NETWORK_WARN, _("Failed to bring down bridge '%s' : %s\n"),
+                 network->def->bridge, strerror(err));
+    }
+
+    if ((err = brDeleteBridge(driver->brctl, network->def->bridge))) {
+        networkLog(NETWORK_WARN, _("Failed to delete bridge '%s' : %s\n"),
+                 network->def->bridge, strerror(err));
+    }
+
+    if (network->dnsmasqPid > 0 &&
+        waitpid(network->dnsmasqPid, NULL, WNOHANG) != network->dnsmasqPid) {
+        kill(network->dnsmasqPid, SIGKILL);
+        if (waitpid(network->dnsmasqPid, NULL, 0) != network->dnsmasqPid)
+            networkLog(NETWORK_WARN,
+                     "%s", _("Got unexpected pid for dnsmasq\n"));
+    }
+
+    network->dnsmasqPid = -1;
+    network->active = 0;
+
+    if (network->newDef) {
+        virNetworkDefFree(network->def);
+        network->def = network->newDef;
+        network->newDef = NULL;
+    }
+
+    if (!network->configFile)
+        virNetworkRemoveInactive(&driver->networks,
+                                 network);
+
+    return 0;
+}
+
+
+static virNetworkPtr networkLookupByUUID(virConnectPtr conn ATTRIBUTE_UNUSED,
+                                              const unsigned char *uuid) {
+    struct network_driver *driver = (struct network_driver *)conn->networkPrivateData;
+    virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, uuid);
+    virNetworkPtr net;
+
+    if (!network) {
+        networkReportError(conn, NULL, NULL, VIR_ERR_NO_NETWORK,
+                         "%s", _("no network with matching uuid"));
+        return NULL;
+    }
+
+    net = virGetNetwork(conn, network->def->name, network->def->uuid);
+    return net;
+}
+static virNetworkPtr networkLookupByName(virConnectPtr conn ATTRIBUTE_UNUSED,
+                                              const char *name) {
+    struct network_driver *driver = (struct network_driver *)conn->networkPrivateData;
+    virNetworkObjPtr network = virNetworkFindByName(driver->networks, name);
+    virNetworkPtr net;
+
+    if (!network) {
+        networkReportError(conn, NULL, NULL, VIR_ERR_NO_NETWORK,
+                         "%s", _("no network with matching name"));
+        return NULL;
+    }
+
+    net = virGetNetwork(conn, network->def->name, network->def->uuid);
+    return net;
+}
+
+static virDrvOpenStatus networkOpenNetwork(virConnectPtr conn,
+                                           xmlURIPtr uri ATTRIBUTE_UNUSED,
+                                           virConnectAuthPtr auth ATTRIBUTE_UNUSED,
+                                           int flags ATTRIBUTE_UNUSED) {
+    if (!driverState)
+        return VIR_DRV_OPEN_DECLINED;
+
+    conn->networkPrivateData = driverState;
+    return VIR_DRV_OPEN_SUCCESS;
+}
+
+static int networkCloseNetwork(virConnectPtr conn) {
+    conn->networkPrivateData = NULL;
+    return 0;
+}
+
+static int networkNumNetworks(virConnectPtr conn) {
+    int nactive = 0;
+    struct network_driver *driver = (struct network_driver *)conn->networkPrivateData;
+    virNetworkObjPtr net = driver->networks;
+    while (net) {
+        if (virNetworkIsActive(net))
+            nactive++;
+        net = net->next;
+    }
+    return nactive;
+}
+
+static int networkListNetworks(virConnectPtr conn, char **const names, int nnames) {
+    struct network_driver *driver = (struct network_driver *)conn->networkPrivateData;
+    virNetworkObjPtr network = driver->networks;
+    int got = 0, i;
+    while (network && got < nnames) {
+        if (virNetworkIsActive(network)) {
+            if (!(names[got] = strdup(network->def->name))) {
+                networkReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
+                     "%s", _("failed to allocate space for VM name string"));
+                goto cleanup;
+            }
+            got++;
+        }
+        network = network->next;
+    }
+    return got;
+
+ cleanup:
+    for (i = 0 ; i < got ; i++)
+        VIR_FREE(names[i]);
+    return -1;
+}
+
+static int networkNumDefinedNetworks(virConnectPtr conn) {
+    int ninactive = 0;
+    struct network_driver *driver = (struct network_driver *)conn->networkPrivateData;
+    virNetworkObjPtr net = driver->networks;
+    while (net) {
+        if (!virNetworkIsActive(net))
+            ninactive++;
+        net = net->next;
+    }
+    return ninactive;
+}
+
+static int networkListDefinedNetworks(virConnectPtr conn, char **const names, int nnames) {
+    struct network_driver *driver = (struct network_driver *)conn->networkPrivateData;
+    virNetworkObjPtr network = driver->networks;
+    int got = 0, i;
+    while (network && got < nnames) {
+        if (!virNetworkIsActive(network)) {
+            if (!(names[got] = strdup(network->def->name))) {
+                networkReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
+                     "%s", _("failed to allocate space for VM name string"));
+                goto cleanup;
+            }
+            got++;
+        }
+        network = network->next;
+    }
+    return got;
+
+ cleanup:
+    for (i = 0 ; i < got ; i++)
+        VIR_FREE(names[i]);
+    return -1;
+}
+
+static virNetworkPtr networkCreate(virConnectPtr conn, const char *xml) {
+ struct network_driver *driver = (struct network_driver *)conn->networkPrivateData;
+    virNetworkDefPtr def;
+    virNetworkObjPtr network;
+    virNetworkPtr net;
+
+    if (!(def = virNetworkDefParseString(conn, xml)))
+        return NULL;
+
+    if (!(network = virNetworkAssignDef(conn,
+                                        &driver->networks,
+                                        def))) {
+        virNetworkDefFree(def);
+        return NULL;
+    }
+
+    if (networkStartNetworkDaemon(conn, driver, network) < 0) {
+        virNetworkRemoveInactive(&driver->networks,
+                                 network);
+        return NULL;
+    }
+
+    net = virGetNetwork(conn, network->def->name, network->def->uuid);
+    return net;
+}
+
+static virNetworkPtr networkDefine(virConnectPtr conn, const char *xml) {
+    struct network_driver *driver = (struct network_driver *)conn->networkPrivateData;
+    virNetworkDefPtr def;
+    virNetworkObjPtr network;
+
+    if (!(def = virNetworkDefParseString(conn, xml)))
+        return NULL;
+
+    if (!(network = virNetworkAssignDef(conn,
+                                        &driver->networks,
+                                        def))) {
+        virNetworkDefFree(def);
+        return NULL;
+    }
+
+    if (virNetworkSaveConfig(conn,
+                             driver->networkConfigDir,
+                             driver->networkAutostartDir,
+                             network) < 0) {
+        virNetworkRemoveInactive(&driver->networks,
+                                 network);
+        return NULL;
+    }
+
+    return virGetNetwork(conn, network->def->name, network->def->uuid);
+}
+
+static int networkUndefine(virNetworkPtr net) {
+    struct network_driver *driver = (struct network_driver *)net->conn->networkPrivateData;
+    virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, net->uuid);
+
+    if (!network) {
+        networkReportError(net->conn, NULL, net, VIR_ERR_INVALID_DOMAIN,
+                         "%s", _("no network with matching uuid"));
+        return -1;
+    }
+
+    if (virNetworkIsActive(network)) {
+        networkReportError(net->conn, NULL, net, VIR_ERR_INTERNAL_ERROR,
+                         "%s", _("network is still active"));
+        return -1;
+    }
+
+    if (virNetworkDeleteConfig(net->conn, network) < 0)
+        return -1;
+
+    virNetworkRemoveInactive(&driver->networks,
+                             network);
+
+    return 0;
+}
+
+static int networkStart(virNetworkPtr net) {
+    struct network_driver *driver = (struct network_driver *)net->conn->networkPrivateData;
+    virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, net->uuid);
+
+    if (!network) {
+        networkReportError(net->conn, NULL, net, VIR_ERR_INVALID_NETWORK,
+                         "%s", _("no network with matching uuid"));
+        return -1;
+    }
+
+    return networkStartNetworkDaemon(net->conn, driver, network);
+}
+
+static int networkDestroy(virNetworkPtr net) {
+    struct network_driver *driver = (struct network_driver *)net->conn->networkPrivateData;
+    virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, net->uuid);
+    int ret;
+
+    if (!network) {
+        networkReportError(net->conn, NULL, net, VIR_ERR_INVALID_NETWORK,
+                         "%s", _("no network with matching uuid"));
+        return -1;
+    }
+
+    ret = networkShutdownNetworkDaemon(net->conn, driver, network);
+
+    return ret;
+}
+
+static char *networkDumpXML(virNetworkPtr net, int flags ATTRIBUTE_UNUSED) {
+    struct network_driver *driver = (struct network_driver *)net->conn->networkPrivateData;
+    virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, net->uuid);
+
+    if (!network) {
+        networkReportError(net->conn, NULL, net, VIR_ERR_INVALID_NETWORK,
+                         "%s", _("no network with matching uuid"));
+        return NULL;
+    }
+
+    return virNetworkDefFormat(net->conn, network->def);
+}
+
+static char *networkGetBridgeName(virNetworkPtr net) {
+    struct network_driver *driver = (struct network_driver *)net->conn->networkPrivateData;
+    virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, net->uuid);
+    char *bridge;
+    if (!network) {
+        networkReportError(net->conn, NULL, net, VIR_ERR_INVALID_NETWORK,
+                         "%s", _("no network with matching id"));
+        return NULL;
+    }
+
+    bridge = strdup(network->def->bridge);
+    if (!bridge) {
+        networkReportError(net->conn, NULL, net, VIR_ERR_NO_MEMORY,
+                 "%s", _("failed to allocate space for network bridge string"));
+        return NULL;
+    }
+    return bridge;
+}
+
+static int networkGetAutostart(virNetworkPtr net,
+                             int *autostart) {
+    struct network_driver *driver = (struct network_driver *)net->conn->networkPrivateData;
+    virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, net->uuid);
+
+    if (!network) {
+        networkReportError(net->conn, NULL, net, VIR_ERR_INVALID_NETWORK,
+                         "%s", _("no network with matching uuid"));
+        return -1;
+    }
+
+    *autostart = network->autostart;
+
+    return 0;
+}
+
+static int networkSetAutostart(virNetworkPtr net,
+                             int autostart) {
+    struct network_driver *driver = (struct network_driver *)net->conn->networkPrivateData;
+    virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, net->uuid);
+
+    if (!network) {
+        networkReportError(net->conn, NULL, net, VIR_ERR_INVALID_NETWORK,
+                         "%s", _("no network with matching uuid"));
+        return -1;
+    }
+
+    autostart = (autostart != 0);
+
+    if (network->autostart == autostart)
+        return 0;
+
+    if (autostart) {
+        int err;
+
+        if ((err = virFileMakePath(driver->networkAutostartDir))) {
+            networkReportError(net->conn, NULL, net, VIR_ERR_INTERNAL_ERROR,
+                             _("cannot create autostart directory %s: %s"),
+                             driver->networkAutostartDir, strerror(err));
+            return -1;
+        }
+
+        if (symlink(network->configFile, network->autostartLink) < 0) {
+            networkReportError(net->conn, NULL, net, VIR_ERR_INTERNAL_ERROR,
+                             _("Failed to create symlink '%s' to '%s': %s"),
+                             network->autostartLink, network->configFile, strerror(errno));
+            return -1;
+        }
+    } else {
+        if (unlink(network->autostartLink) < 0 && errno != ENOENT && errno != ENOTDIR) {
+            networkReportError(net->conn, NULL, net, VIR_ERR_INTERNAL_ERROR,
+                             _("Failed to delete symlink '%s': %s"),
+                             network->autostartLink, strerror(errno));
+            return -1;
+        }
+    }
+
+    network->autostart = autostart;
+
+    return 0;
+}
+
+
+static virNetworkDriver networkDriver = {
+    "Network",
+    networkOpenNetwork, /* open */
+    networkCloseNetwork, /* close */
+    networkNumNetworks, /* numOfNetworks */
+    networkListNetworks, /* listNetworks */
+    networkNumDefinedNetworks, /* numOfDefinedNetworks */
+    networkListDefinedNetworks, /* listDefinedNetworks */
+    networkLookupByUUID, /* networkLookupByUUID */
+    networkLookupByName, /* networkLookupByName */
+    networkCreate, /* networkCreateXML */
+    networkDefine, /* networkDefineXML */
+    networkUndefine, /* networkUndefine */
+    networkStart, /* networkCreate */
+    networkDestroy, /* networkDestroy */
+    networkDumpXML, /* networkDumpXML */
+    networkGetBridgeName, /* networkGetBridgeName */
+    networkGetAutostart, /* networkGetAutostart */
+    networkSetAutostart, /* networkSetAutostart */
+};
+
+static virStateDriver networkStateDriver = {
+    networkStartup,
+    networkShutdown,
+    networkReload,
+    networkActive,
+    NULL
+};
+
+int networkRegister(void) {
+    virRegisterNetworkDriver(&networkDriver);
+    virRegisterStateDriver(&networkStateDriver);
+    return 0;
+}
+
diff --git a/src/network_driver.h b/src/network_driver.h
new file mode 100644 (file)
index 0000000..5951833
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * network_driver.h: core driver methods for managing networks
+ *
+ * Copyright (C) 2006, 2007 Red Hat, Inc.
+ * Copyright (C) 2006 Daniel P. Berrange
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ * Author: Daniel P. Berrange <berrange@redhat.com>
+ */
+
+
+#ifndef __VIR_NETWORK__DRIVER_H
+#define __VIR_NETWORK__DRIVER_H
+
+#include <config.h>
+
+#include "internal.h"
+
+int networkRegister(void);
+
+#endif /* __VIR_NETWORK__DRIVER_H */
index 4c01f5c7e49b588ae4990c074a0a9200bfb423aa..fdd72568384c40c18b0c5a6d1389b0964aa372e7 100644 (file)
@@ -516,7 +516,6 @@ qemudNetworkIfaceConnect(virConnectPtr conn,
                          virDomainNetDefPtr net,
                          int vlan)
 {
-    virNetworkObjPtr network = NULL;
     char *brname;
     char tapfdstr[4+3+32+7];
     char *retval = NULL;
@@ -524,18 +523,24 @@ qemudNetworkIfaceConnect(virConnectPtr conn,
     int tapfd = -1;
 
     if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
-        if (!(network = virNetworkFindByName(driver->networks, net->data.network.name))) {
+        virNetworkPtr network = virNetworkLookupByName(conn,
+                                                      net->data.network.name);
+        if (!network) {
             qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
                              _("Network '%s' not found"),
                              net->data.network.name);
             goto error;
-        } else if (network->def->bridge == NULL) {
+        }
+        brname = virNetworkGetBridgeName(network);
+
+        virNetworkFree(network);
+
+        if (brname == NULL) {
             qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                             _("Network '%s' not active"),
+                             _("Network '%s' is not active"),
                              net->data.network.name);
             goto error;
         }
-        brname = network->def->bridge;
     } else if (net->type == VIR_DOMAIN_NET_TYPE_BRIDGE) {
         brname = net->data.bridge.brname;
     } else {
index 5ea57f039b10c0cf47d645ea7c42b9ba3e55c33a..e77a871f49c857f4fba1e659ce8addbb09ac043a 100644 (file)
@@ -27,7 +27,6 @@
 #include <config.h>
 
 #include "internal.h"
-#include "iptables.h"
 #include "bridge.h"
 #include "capabilities.h"
 #include "network_conf.h"
@@ -53,14 +52,10 @@ struct qemud_driver {
     int nextvmid;
 
     virDomainObjPtr domains;
-    virNetworkObjPtr networks;
 
     brControl *brctl;
-    iptablesContext *iptables;
     char *configDir;
     char *autostartDir;
-    char *networkConfigDir;
-    char *networkAutostartDir;
     char *logDir;
     unsigned int vncTLS : 1;
     unsigned int vncTLSx509verify : 1;
index 0a0efb6bbf2c4b081e3c0cf4a4e733e01bb18dfe..ea5e3bf344b6d8f1654e6937c732659f23779817 100644 (file)
@@ -68,9 +68,7 @@
 /* For storing short-lived temporary files. */
 #define TEMPDIR LOCAL_STATE_DIR "/cache/libvirt"
 
-#ifdef WITH_LIBVIRTD
 static int qemudShutdown(void);
-#endif
 
 /* qemudDebug statements should be changed to use this macro instead. */
 #define DEBUG(fmt,...) VIR_DEBUG(__FILE__, fmt, __VA_ARGS__)
@@ -118,13 +116,6 @@ static void qemudShutdownVMDaemon(virConnectPtr conn,
                                   struct qemud_driver *driver,
                                   virDomainObjPtr vm);
 
-static int qemudStartNetworkDaemon(virConnectPtr conn,
-                                   struct qemud_driver *driver,
-                                   virNetworkObjPtr network);
-
-static int qemudShutdownNetworkDaemon(virConnectPtr conn,
-                                      struct qemud_driver *driver,
-                                      virNetworkObjPtr network);
 
 static int qemudDomainGetMaxVcpus(virDomainPtr dom);
 static int qemudMonitorCommand (const struct qemud_driver *driver,
@@ -137,24 +128,8 @@ static struct qemud_driver *qemu_driver = NULL;
 
 static
 void qemudAutostartConfigs(struct qemud_driver *driver) {
-    virNetworkObjPtr network;
     virDomainObjPtr vm;
 
-    network = driver->networks;
-    while (network != NULL) {
-        virNetworkObjPtr next = network->next;
-
-        if (network->autostart &&
-            !virNetworkIsActive(network) &&
-            qemudStartNetworkDaemon(NULL, driver, network) < 0) {
-            virErrorPtr err = virGetLastError();
-            qemudLog(QEMUD_ERR, _("Failed to autostart network '%s': %s\n"),
-                     network->def->name, err->message);
-        }
-
-        network = next;
-    }
-
     vm = driver->domains;
     while (vm != NULL) {
         virDomainObjPtr next = vm->next;
@@ -171,7 +146,6 @@ void qemudAutostartConfigs(struct qemud_driver *driver) {
     }
 }
 
-#ifdef WITH_LIBVIRTD
 /**
  * qemudStartup:
  *
@@ -225,13 +199,6 @@ qemudStartup(void) {
     if (asprintf (&qemu_driver->autostartDir, "%s/qemu/autostart", base) == -1)
         goto out_of_memory;
 
-    if (asprintf (&qemu_driver->networkConfigDir, "%s/qemu/networks", base) == -1)
-        goto out_of_memory;
-
-    if (asprintf (&qemu_driver->networkAutostartDir, "%s/qemu/networks/autostart",
-                  base) == -1)
-        goto out_of_memory;
-
     VIR_FREE(base);
 
     if ((qemu_driver->caps = qemudCapsInit()) == NULL)
@@ -250,13 +217,6 @@ qemudStartup(void) {
         qemudShutdown();
         return -1;
     }
-    if (virNetworkLoadAllConfigs(NULL,
-                                 &qemu_driver->networks,
-                                 qemu_driver->networkConfigDir,
-                                 qemu_driver->networkAutostartDir) < 0) {
-        qemudShutdown();
-        return -1;
-    }
     qemudAutostartConfigs(qemu_driver);
 
     return 0;
@@ -284,17 +244,6 @@ qemudReload(void) {
                             qemu_driver->configDir,
                             qemu_driver->autostartDir);
 
-    virNetworkLoadAllConfigs(NULL,
-                             &qemu_driver->networks,
-                             qemu_driver->networkConfigDir,
-                             qemu_driver->networkAutostartDir);
-
-     if (qemu_driver->iptables) {
-        qemudLog(QEMUD_INFO,
-                 "%s", _("Reloading iptables rules\n"));
-        iptablesReloadRules(qemu_driver->iptables);
-    }
-
     qemudAutostartConfigs(qemu_driver);
 
     return 0;
@@ -311,7 +260,6 @@ qemudReload(void) {
 static int
 qemudActive(void) {
     virDomainObjPtr dom = qemu_driver->domains;
-    virNetworkObjPtr net = qemu_driver->networks;
 
     while (dom) {
         if (virDomainIsActive(dom))
@@ -319,12 +267,6 @@ qemudActive(void) {
         dom = dom->next;
     }
 
-    while (net) {
-        if (virNetworkIsActive(net))
-            return 1;
-        net = net->next;
-    }
-
     /* Otherwise we're happy to deal with a shutdown */
     return 0;
 }
@@ -337,7 +279,6 @@ qemudActive(void) {
 static int
 qemudShutdown(void) {
     virDomainObjPtr vm;
-    virNetworkObjPtr network;
 
     if (!qemu_driver)
         return -1;
@@ -365,41 +306,18 @@ qemudShutdown(void) {
     }
     qemu_driver->domains = NULL;
 
-    /* shutdown active networks */
-    network = qemu_driver->networks;
-    while (network) {
-        virNetworkObjPtr next = network->next;
-        if (virNetworkIsActive(network))
-            qemudShutdownNetworkDaemon(NULL, qemu_driver, network);
-        network = next;
-    }
-
-    /* free inactive networks */
-    network = qemu_driver->networks;
-    while (network) {
-        virNetworkObjPtr next = network->next;
-        virNetworkObjFree(network);
-        network = next;
-    }
-    qemu_driver->networks = NULL;
-
     VIR_FREE(qemu_driver->logDir);
     VIR_FREE(qemu_driver->configDir);
     VIR_FREE(qemu_driver->autostartDir);
-    VIR_FREE(qemu_driver->networkConfigDir);
-    VIR_FREE(qemu_driver->networkAutostartDir);
     VIR_FREE(qemu_driver->vncTLSx509certdir);
 
     if (qemu_driver->brctl)
         brShutdown(qemu_driver->brctl);
-    if (qemu_driver->iptables)
-        iptablesContextFree(qemu_driver->iptables);
 
     VIR_FREE(qemu_driver);
 
     return 0;
 }
-#endif
 
 /* Return -1 for error, 1 to continue reading and 0 for success */
 typedef int qemudHandlerMonitorOutput(virConnectPtr conn,
@@ -1098,547 +1016,6 @@ static int qemudDispatchVMFailure(struct qemud_driver *driver, virDomainObjPtr v
     return 0;
 }
 
-static int
-qemudBuildDnsmasqArgv(virConnectPtr conn,
-                      virNetworkObjPtr network,
-                      const char ***argv) {
-    int i, len, r;
-    char buf[PATH_MAX];
-
-    len =
-        1 + /* dnsmasq */
-        1 + /* --keep-in-foreground */
-        1 + /* --strict-order */
-        1 + /* --bind-interfaces */
-        (network->def->domain?2:0) + /* --domain name */
-        2 + /* --pid-file "" */
-        2 + /* --conf-file "" */
-        /*2 + *//* --interface virbr0 */
-        2 + /* --except-interface lo */
-        2 + /* --listen-address 10.0.0.1 */
-        1 + /* --dhcp-leasefile=path */
-        (2 * network->def->nranges) + /* --dhcp-range 10.0.0.2,10.0.0.254 */
-        /*  --dhcp-host 01:23:45:67:89:0a,hostname,10.0.0.3 */
-        (2 * network->def->nhosts) +
-        1;  /* NULL */
-
-    if (VIR_ALLOC_N(*argv, len) < 0)
-        goto no_memory;
-
-#define APPEND_ARG(v, n, s) do {     \
-        if (!((v)[(n)] = strdup(s))) \
-            goto no_memory;          \
-    } while (0)
-
-    i = 0;
-
-    APPEND_ARG(*argv, i++, DNSMASQ);
-
-    APPEND_ARG(*argv, i++, "--keep-in-foreground");
-    /*
-     * Needed to ensure dnsmasq uses same algorithm for processing
-     * multiple namedriver entries in /etc/resolv.conf as GLibC.
-     */
-    APPEND_ARG(*argv, i++, "--strict-order");
-    APPEND_ARG(*argv, i++, "--bind-interfaces");
-
-    if (network->def->domain) {
-       APPEND_ARG(*argv, i++, "--domain");
-       APPEND_ARG(*argv, i++, network->def->domain);
-    }
-
-    APPEND_ARG(*argv, i++, "--pid-file");
-    APPEND_ARG(*argv, i++, "");
-
-    APPEND_ARG(*argv, i++, "--conf-file");
-    APPEND_ARG(*argv, i++, "");
-
-    /*
-     * XXX does not actually work, due to some kind of
-     * race condition setting up ipv6 addresses on the
-     * interface. A sleep(10) makes it work, but that's
-     * clearly not practical
-     *
-     * APPEND_ARG(*argv, i++, "--interface");
-     * APPEND_ARG(*argv, i++, network->def->bridge);
-     */
-    APPEND_ARG(*argv, i++, "--listen-address");
-    APPEND_ARG(*argv, i++, network->def->ipAddress);
-
-    APPEND_ARG(*argv, i++, "--except-interface");
-    APPEND_ARG(*argv, i++, "lo");
-
-    /*
-     * NB, dnsmasq command line arg bug means we need to
-     * use a single arg '--dhcp-leasefile=path' rather than
-     * two separate args in '--dhcp-leasefile path' style
-     */
-    snprintf(buf, sizeof(buf), "--dhcp-leasefile=%s/lib/libvirt/dhcp-%s.leases",
-             LOCAL_STATE_DIR, network->def->name);
-    APPEND_ARG(*argv, i++, buf);
-
-    for (r = 0 ; r < network->def->nranges ; r++) {
-        snprintf(buf, sizeof(buf), "%s,%s",
-                 network->def->ranges[r].start,
-                 network->def->ranges[r].end);
-
-        APPEND_ARG(*argv, i++, "--dhcp-range");
-        APPEND_ARG(*argv, i++, buf);
-    }
-
-    for (r = 0 ; r < network->def->nhosts ; r++) {
-        virNetworkDHCPHostDefPtr host = &(network->def->hosts[r]);
-        if ((host->mac) && (host->name)) {
-            snprintf(buf, sizeof(buf), "%s,%s,%s",
-                     host->mac, host->name, host->ip);
-        } else if (host->mac) {
-            snprintf(buf, sizeof(buf), "%s,%s",
-                     host->mac, host->ip);
-        } else if (host->name) {
-            snprintf(buf, sizeof(buf), "%s,%s",
-                     host->name, host->ip);
-        } else
-            continue;
-
-        APPEND_ARG(*argv, i++, "--dhcp-host");
-        APPEND_ARG(*argv, i++, buf);
-    }
-
-#undef APPEND_ARG
-
-    return 0;
-
- no_memory:
-    if (argv) {
-        for (i = 0; (*argv)[i]; i++)
-            VIR_FREE((*argv)[i]);
-        VIR_FREE(*argv);
-    }
-    qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
-                     "%s", _("failed to allocate space for dnsmasq argv"));
-    return -1;
-}
-
-
-static int
-dhcpStartDhcpDaemon(virConnectPtr conn,
-                    virNetworkObjPtr network)
-{
-    const char **argv;
-    int ret, i;
-
-    if (network->def->ipAddress == NULL) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         "%s", _("cannot start dhcp daemon without IP address for server"));
-        return -1;
-    }
-
-    argv = NULL;
-    if (qemudBuildDnsmasqArgv(conn, network, &argv) < 0)
-        return -1;
-
-    ret = virExec(conn, argv, NULL, NULL,
-                  &network->dnsmasqPid, -1, NULL, NULL, VIR_EXEC_NONBLOCK);
-
-    for (i = 0; argv[i]; i++)
-        VIR_FREE(argv[i]);
-    VIR_FREE(argv);
-
-    return ret;
-}
-
-static int
-qemudAddMasqueradingIptablesRules(virConnectPtr conn,
-                      struct qemud_driver *driver,
-                      virNetworkObjPtr network) {
-    int err;
-    /* allow forwarding packets from the bridge interface */
-    if ((err = iptablesAddForwardAllowOut(driver->iptables,
-                                          network->def->network,
-                                          network->def->bridge,
-                                          network->def->forwardDev))) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to add iptables rule to allow forwarding from '%s' : %s\n"),
-                         network->def->bridge, strerror(err));
-        goto masqerr1;
-    }
-
-    /* allow forwarding packets to the bridge interface if they are part of an existing connection */
-    if ((err = iptablesAddForwardAllowRelatedIn(driver->iptables,
-                                         network->def->network,
-                                         network->def->bridge,
-                                         network->def->forwardDev))) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to add iptables rule to allow forwarding to '%s' : %s\n"),
-                         network->def->bridge, strerror(err));
-        goto masqerr2;
-    }
-
-    /* enable masquerading */
-    if ((err = iptablesAddForwardMasquerade(driver->iptables,
-                                            network->def->network,
-                                            network->def->forwardDev))) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to add iptables rule to enable masquerading : %s\n"),
-                         strerror(err));
-        goto masqerr3;
-    }
-
-    return 1;
-
- masqerr3:
-    iptablesRemoveForwardAllowRelatedIn(driver->iptables,
-                                 network->def->network,
-                                 network->def->bridge,
-                                 network->def->forwardDev);
- masqerr2:
-    iptablesRemoveForwardAllowOut(driver->iptables,
-                                  network->def->network,
-                                  network->def->bridge,
-                                  network->def->forwardDev);
- masqerr1:
-    return 0;
-}
-
-static int
-qemudAddRoutingIptablesRules(virConnectPtr conn,
-                      struct qemud_driver *driver,
-                      virNetworkObjPtr network) {
-    int err;
-    /* allow routing packets from the bridge interface */
-    if ((err = iptablesAddForwardAllowOut(driver->iptables,
-                                          network->def->network,
-                                          network->def->bridge,
-                                          network->def->forwardDev))) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to add iptables rule to allow routing from '%s' : %s\n"),
-                         network->def->bridge, strerror(err));
-        goto routeerr1;
-    }
-
-    /* allow routing packets to the bridge interface */
-    if ((err = iptablesAddForwardAllowIn(driver->iptables,
-                                         network->def->network,
-                                         network->def->bridge,
-                                         network->def->forwardDev))) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to add iptables rule to allow routing to '%s' : %s\n"),
-                         network->def->bridge, strerror(err));
-        goto routeerr2;
-    }
-
-    return 1;
-
-
- routeerr2:
-    iptablesRemoveForwardAllowOut(driver->iptables,
-                                  network->def->network,
-                                  network->def->bridge,
-                                  network->def->forwardDev);
- routeerr1:
-    return 0;
-}
-
-static int
-qemudAddIptablesRules(virConnectPtr conn,
-                      struct qemud_driver *driver,
-                      virNetworkObjPtr network) {
-    int err;
-
-    if (!driver->iptables && !(driver->iptables = iptablesContextNew())) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
-                     "%s", _("failed to allocate space for IP tables support"));
-        return 0;
-    }
-
-
-    /* allow DHCP requests through to dnsmasq */
-    if ((err = iptablesAddTcpInput(driver->iptables, network->def->bridge, 67))) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to add iptables rule to allow DHCP requests from '%s' : %s"),
-                         network->def->bridge, strerror(err));
-        goto err1;
-    }
-
-    if ((err = iptablesAddUdpInput(driver->iptables, network->def->bridge, 67))) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to add iptables rule to allow DHCP requests from '%s' : %s"),
-                         network->def->bridge, strerror(err));
-        goto err2;
-    }
-
-    /* allow DNS requests through to dnsmasq */
-    if ((err = iptablesAddTcpInput(driver->iptables, network->def->bridge, 53))) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to add iptables rule to allow DNS requests from '%s' : %s"),
-                         network->def->bridge, strerror(err));
-        goto err3;
-    }
-
-    if ((err = iptablesAddUdpInput(driver->iptables, network->def->bridge, 53))) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to add iptables rule to allow DNS requests from '%s' : %s"),
-                         network->def->bridge, strerror(err));
-        goto err4;
-    }
-
-
-    /* Catch all rules to block forwarding to/from bridges */
-
-    if ((err = iptablesAddForwardRejectOut(driver->iptables, network->def->bridge))) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to add iptables rule to block outbound traffic from '%s' : %s"),
-                         network->def->bridge, strerror(err));
-        goto err5;
-    }
-
-    if ((err = iptablesAddForwardRejectIn(driver->iptables, network->def->bridge))) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to add iptables rule to block inbound traffic to '%s' : %s"),
-                         network->def->bridge, strerror(err));
-        goto err6;
-    }
-
-    /* Allow traffic between guests on the same bridge */
-    if ((err = iptablesAddForwardAllowCross(driver->iptables, network->def->bridge))) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to add iptables rule to allow cross bridge traffic on '%s' : %s"),
-                         network->def->bridge, strerror(err));
-        goto err7;
-    }
-
-
-    /* If masquerading is enabled, set up the rules*/
-    if (network->def->forwardType == VIR_NETWORK_FORWARD_NAT &&
-        !qemudAddMasqueradingIptablesRules(conn, driver, network))
-        goto err8;
-    /* else if routing is enabled, set up the rules*/
-    else if (network->def->forwardType == VIR_NETWORK_FORWARD_ROUTE &&
-             !qemudAddRoutingIptablesRules(conn, driver, network))
-        goto err8;
-
-    iptablesSaveRules(driver->iptables);
-
-    return 1;
-
- err8:
-    iptablesRemoveForwardAllowCross(driver->iptables,
-                                    network->def->bridge);
- err7:
-    iptablesRemoveForwardRejectIn(driver->iptables,
-                                  network->def->bridge);
- err6:
-    iptablesRemoveForwardRejectOut(driver->iptables,
-                                   network->def->bridge);
- err5:
-    iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 53);
- err4:
-    iptablesRemoveTcpInput(driver->iptables, network->def->bridge, 53);
- err3:
-    iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 67);
- err2:
-    iptablesRemoveTcpInput(driver->iptables, network->def->bridge, 67);
- err1:
-    return 0;
-}
-
-static void
-qemudRemoveIptablesRules(struct qemud_driver *driver,
-                         virNetworkObjPtr network) {
-    if (network->def->forwardType != VIR_NETWORK_FORWARD_NONE) {
-        iptablesRemoveForwardMasquerade(driver->iptables,
-                                        network->def->network,
-                                        network->def->forwardDev);
-
-        if (network->def->forwardType == VIR_NETWORK_FORWARD_NAT)
-            iptablesRemoveForwardAllowRelatedIn(driver->iptables,
-                                                network->def->network,
-                                                network->def->bridge,
-                                                network->def->forwardDev);
-        else if (network->def->forwardType == VIR_NETWORK_FORWARD_ROUTE)
-            iptablesRemoveForwardAllowIn(driver->iptables,
-                                         network->def->network,
-                                         network->def->bridge,
-                                         network->def->forwardDev);
-
-        iptablesRemoveForwardAllowOut(driver->iptables,
-                                      network->def->network,
-                                      network->def->bridge,
-                                      network->def->forwardDev);
-    }
-    iptablesRemoveForwardAllowCross(driver->iptables, network->def->bridge);
-    iptablesRemoveForwardRejectIn(driver->iptables, network->def->bridge);
-    iptablesRemoveForwardRejectOut(driver->iptables, network->def->bridge);
-    iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 53);
-    iptablesRemoveTcpInput(driver->iptables, network->def->bridge, 53);
-    iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 67);
-    iptablesRemoveTcpInput(driver->iptables, network->def->bridge, 67);
-    iptablesSaveRules(driver->iptables);
-}
-
-static int
-qemudEnableIpForwarding(void)
-{
-#define PROC_IP_FORWARD "/proc/sys/net/ipv4/ip_forward"
-
-    int fd, ret;
-
-    if ((fd = open(PROC_IP_FORWARD, O_WRONLY|O_TRUNC)) == -1)
-        return 0;
-
-    if (safewrite(fd, "1\n", 2) < 0)
-        ret = 0;
-
-    close (fd);
-
-    return 1;
-
-#undef PROC_IP_FORWARD
-}
-
-static int qemudStartNetworkDaemon(virConnectPtr conn,
-                                   struct qemud_driver *driver,
-                                   virNetworkObjPtr network) {
-    int err;
-
-    if (virNetworkIsActive(network)) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         "%s", _("network is already active"));
-        return -1;
-    }
-
-    if (!driver->brctl && (err = brInit(&driver->brctl))) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("cannot initialize bridge support: %s"), strerror(err));
-        return -1;
-    }
-
-    if ((err = brAddBridge(driver->brctl, &network->def->bridge))) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("cannot create bridge '%s' : %s"),
-                         network->def->bridge, strerror(err));
-        return -1;
-    }
-
-
-    if (brSetForwardDelay(driver->brctl, network->def->bridge, network->def->delay) < 0)
-        goto err_delbr;
-
-    if (brSetEnableSTP(driver->brctl, network->def->bridge, network->def->stp ? 1 : 0) < 0)
-        goto err_delbr;
-
-    if (network->def->ipAddress &&
-        (err = brSetInetAddress(driver->brctl, network->def->bridge, network->def->ipAddress))) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("cannot set IP address on bridge '%s' to '%s' : %s"),
-                         network->def->bridge, network->def->ipAddress, strerror(err));
-        goto err_delbr;
-    }
-
-    if (network->def->netmask &&
-        (err = brSetInetNetmask(driver->brctl, network->def->bridge, network->def->netmask))) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("cannot set netmask on bridge '%s' to '%s' : %s"),
-                         network->def->bridge, network->def->netmask, strerror(err));
-        goto err_delbr;
-    }
-
-    if (network->def->ipAddress &&
-        (err = brSetInterfaceUp(driver->brctl, network->def->bridge, 1))) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to bring the bridge '%s' up : %s"),
-                         network->def->bridge, strerror(err));
-        goto err_delbr;
-    }
-
-    if (!qemudAddIptablesRules(conn, driver, network))
-        goto err_delbr1;
-
-    if (network->def->forwardType != VIR_NETWORK_FORWARD_NONE &&
-        !qemudEnableIpForwarding()) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
-                         _("failed to enable IP forwarding : %s"), strerror(err));
-        goto err_delbr2;
-    }
-
-    if (network->def->nranges &&
-        dhcpStartDhcpDaemon(conn, network) < 0)
-        goto err_delbr2;
-
-    network->active = 1;
-
-    return 0;
-
- err_delbr2:
-    qemudRemoveIptablesRules(driver, network);
-
- err_delbr1:
-    if (network->def->ipAddress &&
-        (err = brSetInterfaceUp(driver->brctl, network->def->bridge, 0))) {
-        qemudLog(QEMUD_WARN, _("Failed to bring down bridge '%s' : %s\n"),
-                 network->def->bridge, strerror(err));
-    }
-
- err_delbr:
-    if ((err = brDeleteBridge(driver->brctl, network->def->bridge))) {
-        qemudLog(QEMUD_WARN, _("Failed to delete bridge '%s' : %s\n"),
-                 network->def->bridge, strerror(err));
-    }
-
-    return -1;
-}
-
-
-static int qemudShutdownNetworkDaemon(virConnectPtr conn ATTRIBUTE_UNUSED,
-                                      struct qemud_driver *driver,
-                                      virNetworkObjPtr network) {
-    int err;
-
-    qemudLog(QEMUD_INFO, _("Shutting down network '%s'\n"), network->def->name);
-
-    if (!virNetworkIsActive(network))
-        return 0;
-
-    if (network->dnsmasqPid > 0)
-        kill(network->dnsmasqPid, SIGTERM);
-
-    qemudRemoveIptablesRules(driver, network);
-
-    if (network->def->ipAddress &&
-        (err = brSetInterfaceUp(driver->brctl, network->def->bridge, 0))) {
-        qemudLog(QEMUD_WARN, _("Failed to bring down bridge '%s' : %s\n"),
-                 network->def->bridge, strerror(err));
-    }
-
-    if ((err = brDeleteBridge(driver->brctl, network->def->bridge))) {
-        qemudLog(QEMUD_WARN, _("Failed to delete bridge '%s' : %s\n"),
-                 network->def->bridge, strerror(err));
-    }
-
-    if (network->dnsmasqPid > 0 &&
-        waitpid(network->dnsmasqPid, NULL, WNOHANG) != network->dnsmasqPid) {
-        kill(network->dnsmasqPid, SIGKILL);
-        if (waitpid(network->dnsmasqPid, NULL, 0) != network->dnsmasqPid)
-            qemudLog(QEMUD_WARN,
-                     "%s", _("Got unexpected pid for dnsmasq\n"));
-    }
-
-    network->dnsmasqPid = -1;
-    network->active = 0;
-
-    if (network->newDef) {
-        virNetworkDefFree(network->def);
-        network->def = network->newDef;
-        network->newDef = NULL;
-    }
-
-    if (!network->configFile)
-        virNetworkRemoveInactive(&driver->networks,
-                                 network);
-
-    return 0;
-}
-
 
 static void qemudDispatchVMEvent(int fd, int events, void *opaque) {
     struct qemud_driver *driver = (struct qemud_driver *)opaque;
@@ -3690,323 +3067,6 @@ done:
     return ret;
 }
 
-static virNetworkPtr qemudNetworkLookupByUUID(virConnectPtr conn ATTRIBUTE_UNUSED,
-                                              const unsigned char *uuid) {
-    struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData;
-    virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, uuid);
-    virNetworkPtr net;
-
-    if (!network) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_NO_NETWORK,
-                         "%s", _("no network with matching uuid"));
-        return NULL;
-    }
-
-    net = virGetNetwork(conn, network->def->name, network->def->uuid);
-    return net;
-}
-static virNetworkPtr qemudNetworkLookupByName(virConnectPtr conn ATTRIBUTE_UNUSED,
-                                              const char *name) {
-    struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData;
-    virNetworkObjPtr network = virNetworkFindByName(driver->networks, name);
-    virNetworkPtr net;
-
-    if (!network) {
-        qemudReportError(conn, NULL, NULL, VIR_ERR_NO_NETWORK,
-                         "%s", _("no network with matching name"));
-        return NULL;
-    }
-
-    net = virGetNetwork(conn, network->def->name, network->def->uuid);
-    return net;
-}
-
-static virDrvOpenStatus qemudOpenNetwork(virConnectPtr conn,
-                                         xmlURIPtr uri ATTRIBUTE_UNUSED,
-                                         virConnectAuthPtr auth ATTRIBUTE_UNUSED,
-                                         int flags ATTRIBUTE_UNUSED) {
-    if (!qemu_driver)
-        return VIR_DRV_OPEN_DECLINED;
-
-    conn->networkPrivateData = qemu_driver;
-    return VIR_DRV_OPEN_SUCCESS;
-}
-
-static int qemudCloseNetwork(virConnectPtr conn) {
-    conn->networkPrivateData = NULL;
-    return 0;
-}
-
-static int qemudNumNetworks(virConnectPtr conn) {
-    int nactive = 0;
-    struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData;
-    virNetworkObjPtr net = driver->networks;
-    while (net) {
-        if (virNetworkIsActive(net))
-            nactive++;
-        net = net->next;
-    }
-    return nactive;
-}
-
-static int qemudListNetworks(virConnectPtr conn, char **const names, int nnames) {
-    struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData;
-    virNetworkObjPtr network = driver->networks;
-    int got = 0, i;
-    while (network && got < nnames) {
-        if (virNetworkIsActive(network)) {
-            if (!(names[got] = strdup(network->def->name))) {
-                qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
-                     "%s", _("failed to allocate space for VM name string"));
-                goto cleanup;
-            }
-            got++;
-        }
-        network = network->next;
-    }
-    return got;
-
- cleanup:
-    for (i = 0 ; i < got ; i++)
-        VIR_FREE(names[i]);
-    return -1;
-}
-
-static int qemudNumDefinedNetworks(virConnectPtr conn) {
-    int ninactive = 0;
-    struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData;
-    virNetworkObjPtr net = driver->networks;
-    while (net) {
-        if (!virNetworkIsActive(net))
-            ninactive++;
-        net = net->next;
-    }
-    return ninactive;
-}
-
-static int qemudListDefinedNetworks(virConnectPtr conn, char **const names, int nnames) {
-    struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData;
-    virNetworkObjPtr network = driver->networks;
-    int got = 0, i;
-    while (network && got < nnames) {
-        if (!virNetworkIsActive(network)) {
-            if (!(names[got] = strdup(network->def->name))) {
-                qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
-                     "%s", _("failed to allocate space for VM name string"));
-                goto cleanup;
-            }
-            got++;
-        }
-        network = network->next;
-    }
-    return got;
-
- cleanup:
-    for (i = 0 ; i < got ; i++)
-        VIR_FREE(names[i]);
-    return -1;
-}
-
-static virNetworkPtr qemudNetworkCreate(virConnectPtr conn, const char *xml) {
- struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData;
-    virNetworkDefPtr def;
-    virNetworkObjPtr network;
-    virNetworkPtr net;
-
-    if (!(def = virNetworkDefParseString(conn, xml)))
-        return NULL;
-
-    if (!(network = virNetworkAssignDef(conn,
-                                        &driver->networks,
-                                        def))) {
-        virNetworkDefFree(def);
-        return NULL;
-    }
-
-    if (qemudStartNetworkDaemon(conn, driver, network) < 0) {
-        virNetworkRemoveInactive(&driver->networks,
-                                 network);
-        return NULL;
-    }
-
-    net = virGetNetwork(conn, network->def->name, network->def->uuid);
-    return net;
-}
-
-static virNetworkPtr qemudNetworkDefine(virConnectPtr conn, const char *xml) {
-    struct qemud_driver *driver = (struct qemud_driver *)conn->networkPrivateData;
-    virNetworkDefPtr def;
-    virNetworkObjPtr network;
-
-    if (!(def = virNetworkDefParseString(conn, xml)))
-        return NULL;
-
-    if (!(network = virNetworkAssignDef(conn,
-                                        &driver->networks,
-                                        def))) {
-        virNetworkDefFree(def);
-        return NULL;
-    }
-
-    if (virNetworkSaveConfig(conn,
-                             driver->networkConfigDir,
-                             driver->networkAutostartDir,
-                             network) < 0) {
-        virNetworkRemoveInactive(&driver->networks,
-                                 network);
-        return NULL;
-    }
-
-    return virGetNetwork(conn, network->def->name, network->def->uuid);
-}
-
-static int qemudNetworkUndefine(virNetworkPtr net) {
-    struct qemud_driver *driver = (struct qemud_driver *)net->conn->networkPrivateData;
-    virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, net->uuid);
-
-    if (!network) {
-        qemudReportError(net->conn, NULL, net, VIR_ERR_INVALID_DOMAIN,
-                         "%s", _("no network with matching uuid"));
-        return -1;
-    }
-
-    if (virNetworkIsActive(network)) {
-        qemudReportError(net->conn, NULL, net, VIR_ERR_INTERNAL_ERROR,
-                         "%s", _("network is still active"));
-        return -1;
-    }
-
-    if (virNetworkDeleteConfig(net->conn, network) < 0)
-        return -1;
-
-    virNetworkRemoveInactive(&driver->networks,
-                             network);
-
-    return 0;
-}
-
-static int qemudNetworkStart(virNetworkPtr net) {
-    struct qemud_driver *driver = (struct qemud_driver *)net->conn->networkPrivateData;
-    virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, net->uuid);
-
-    if (!network) {
-        qemudReportError(net->conn, NULL, net, VIR_ERR_INVALID_NETWORK,
-                         "%s", _("no network with matching uuid"));
-        return -1;
-    }
-
-    return qemudStartNetworkDaemon(net->conn, driver, network);
-}
-
-static int qemudNetworkDestroy(virNetworkPtr net) {
-    struct qemud_driver *driver = (struct qemud_driver *)net->conn->networkPrivateData;
-    virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, net->uuid);
-    int ret;
-
-    if (!network) {
-        qemudReportError(net->conn, NULL, net, VIR_ERR_INVALID_NETWORK,
-                         "%s", _("no network with matching uuid"));
-        return -1;
-    }
-
-    ret = qemudShutdownNetworkDaemon(net->conn, driver, network);
-
-    return ret;
-}
-
-static char *qemudNetworkDumpXML(virNetworkPtr net, int flags ATTRIBUTE_UNUSED) {
-    struct qemud_driver *driver = (struct qemud_driver *)net->conn->networkPrivateData;
-    virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, net->uuid);
-
-    if (!network) {
-        qemudReportError(net->conn, NULL, net, VIR_ERR_INVALID_NETWORK,
-                         "%s", _("no network with matching uuid"));
-        return NULL;
-    }
-
-    return virNetworkDefFormat(net->conn, network->def);
-}
-
-static char *qemudNetworkGetBridgeName(virNetworkPtr net) {
-    struct qemud_driver *driver = (struct qemud_driver *)net->conn->networkPrivateData;
-    virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, net->uuid);
-    char *bridge;
-    if (!network) {
-        qemudReportError(net->conn, NULL, net, VIR_ERR_INVALID_NETWORK,
-                         "%s", _("no network with matching id"));
-        return NULL;
-    }
-
-    bridge = strdup(network->def->bridge);
-    if (!bridge) {
-        qemudReportError(net->conn, NULL, net, VIR_ERR_NO_MEMORY,
-                 "%s", _("failed to allocate space for network bridge string"));
-        return NULL;
-    }
-    return bridge;
-}
-
-static int qemudNetworkGetAutostart(virNetworkPtr net,
-                             int *autostart) {
-    struct qemud_driver *driver = (struct qemud_driver *)net->conn->networkPrivateData;
-    virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, net->uuid);
-
-    if (!network) {
-        qemudReportError(net->conn, NULL, net, VIR_ERR_INVALID_NETWORK,
-                         "%s", _("no network with matching uuid"));
-        return -1;
-    }
-
-    *autostart = network->autostart;
-
-    return 0;
-}
-
-static int qemudNetworkSetAutostart(virNetworkPtr net,
-                             int autostart) {
-    struct qemud_driver *driver = (struct qemud_driver *)net->conn->networkPrivateData;
-    virNetworkObjPtr network = virNetworkFindByUUID(driver->networks, net->uuid);
-
-    if (!network) {
-        qemudReportError(net->conn, NULL, net, VIR_ERR_INVALID_NETWORK,
-                         "%s", _("no network with matching uuid"));
-        return -1;
-    }
-
-    autostart = (autostart != 0);
-
-    if (network->autostart == autostart)
-        return 0;
-
-    if (autostart) {
-        int err;
-
-        if ((err = virFileMakePath(driver->networkAutostartDir))) {
-            qemudReportError(net->conn, NULL, net, VIR_ERR_INTERNAL_ERROR,
-                             _("cannot create autostart directory %s: %s"),
-                             driver->networkAutostartDir, strerror(err));
-            return -1;
-        }
-
-        if (symlink(network->configFile, network->autostartLink) < 0) {
-            qemudReportError(net->conn, NULL, net, VIR_ERR_INTERNAL_ERROR,
-                             _("Failed to create symlink '%s' to '%s': %s"),
-                             network->autostartLink, network->configFile, strerror(errno));
-            return -1;
-        }
-    } else {
-        if (unlink(network->autostartLink) < 0 && errno != ENOENT && errno != ENOTDIR) {
-            qemudReportError(net->conn, NULL, net, VIR_ERR_INTERNAL_ERROR,
-                             _("Failed to delete symlink '%s': %s"),
-                             network->autostartLink, strerror(errno));
-            return -1;
-        }
-    }
-
-    network->autostart = autostart;
-
-    return 0;
-}
 
 static virDriver qemuDriver = {
     VIR_DRV_QEMU,
@@ -4080,42 +3140,17 @@ static virDriver qemuDriver = {
 #endif
 };
 
-static virNetworkDriver qemuNetworkDriver = {
-    "QEMU",
-    qemudOpenNetwork, /* open */
-    qemudCloseNetwork, /* close */
-    qemudNumNetworks, /* numOfNetworks */
-    qemudListNetworks, /* listNetworks */
-    qemudNumDefinedNetworks, /* numOfDefinedNetworks */
-    qemudListDefinedNetworks, /* listDefinedNetworks */
-    qemudNetworkLookupByUUID, /* networkLookupByUUID */
-    qemudNetworkLookupByName, /* networkLookupByName */
-    qemudNetworkCreate, /* networkCreateXML */
-    qemudNetworkDefine, /* networkDefineXML */
-    qemudNetworkUndefine, /* networkUndefine */
-    qemudNetworkStart, /* networkCreate */
-    qemudNetworkDestroy, /* networkDestroy */
-    qemudNetworkDumpXML, /* networkDumpXML */
-    qemudNetworkGetBridgeName, /* networkGetBridgeName */
-    qemudNetworkGetAutostart, /* networkGetAutostart */
-    qemudNetworkSetAutostart, /* networkSetAutostart */
-};
 
-#ifdef WITH_LIBVIRTD
 static virStateDriver qemuStateDriver = {
     .initialize = qemudStartup,
     .cleanup = qemudShutdown,
     .reload = qemudReload,
     .active = qemudActive,
 };
-#endif
 
 int qemudRegister(void) {
     virRegisterDriver(&qemuDriver);
-    virRegisterNetworkDriver(&qemuNetworkDriver);
-#ifdef WITH_LIBVIRTD
     virRegisterStateDriver(&qemuStateDriver);
-#endif
     return 0;
 }