Update my email address in AUTHORS.in
[libvirt.git] / src / network / bridge_driver.c
1 /*
2  * bridge_driver.c: core driver methods for managing network
3  *
4  * Copyright (C) 2006-2013 Red Hat, Inc.
5  * Copyright (C) 2006 Daniel P. Berrange
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library.  If not, see
19  * <http://www.gnu.org/licenses/>.
20  *
21  * Author: Daniel P. Berrange <berrange@redhat.com>
22  */
23
24 #include <config.h>
25
26 #include <sys/types.h>
27 #include <sys/poll.h>
28 #include <limits.h>
29 #include <string.h>
30 #include <stdio.h>
31 #include <stdarg.h>
32 #include <stdlib.h>
33 #include <unistd.h>
34 #include <errno.h>
35 #include <sys/utsname.h>
36 #include <sys/stat.h>
37 #include <fcntl.h>
38 #include <signal.h>
39 #include <paths.h>
40 #include <pwd.h>
41 #include <sys/wait.h>
42 #include <sys/ioctl.h>
43 #include <net/if.h>
44 #if HAVE_SYS_SYSCTL_H
45 # include <sys/sysctl.h>
46 #endif
47
48 #include "virerror.h"
49 #include "datatypes.h"
50 #include "bridge_driver.h"
51 #include "bridge_driver_platform.h"
52 #include "network_conf.h"
53 #include "device_conf.h"
54 #include "driver.h"
55 #include "virbuffer.h"
56 #include "virpidfile.h"
57 #include "vircommand.h"
58 #include "viralloc.h"
59 #include "viruuid.h"
60 #include "viriptables.h"
61 #include "virlog.h"
62 #include "virdnsmasq.h"
63 #include "configmake.h"
64 #include "virnetdev.h"
65 #include "virpci.h"
66 #include "virnetdevbridge.h"
67 #include "virnetdevtap.h"
68 #include "virnetdevvportprofile.h"
69 #include "virdbus.h"
70 #include "virfile.h"
71 #include "virstring.h"
72 #include "viraccessapicheck.h"
73
74 #define VIR_FROM_THIS VIR_FROM_NETWORK
75
76 static void networkDriverLock(virNetworkDriverStatePtr driver)
77 {
78     virMutexLock(&driver->lock);
79 }
80 static void networkDriverUnlock(virNetworkDriverStatePtr driver)
81 {
82     virMutexUnlock(&driver->lock);
83 }
84
85 static int networkStateCleanup(void);
86
87 static int networkStartNetwork(virNetworkDriverStatePtr driver,
88                                virNetworkObjPtr network);
89
90 static int networkShutdownNetwork(virNetworkDriverStatePtr driver,
91                                   virNetworkObjPtr network);
92
93 static int networkStartNetworkVirtual(virNetworkDriverStatePtr driver,
94                                      virNetworkObjPtr network);
95
96 static int networkShutdownNetworkVirtual(virNetworkDriverStatePtr driver,
97                                          virNetworkObjPtr network);
98
99 static int networkStartNetworkExternal(virNetworkDriverStatePtr driver,
100                                      virNetworkObjPtr network);
101
102 static int networkShutdownNetworkExternal(virNetworkDriverStatePtr driver,
103                                         virNetworkObjPtr network);
104
105 static void networkReloadFirewallRules(virNetworkDriverStatePtr driver);
106 static void networkRefreshDaemons(virNetworkDriverStatePtr driver);
107
108 static int networkPlugBandwidth(virNetworkObjPtr net,
109                                 virDomainNetDefPtr iface);
110 static int networkUnplugBandwidth(virNetworkObjPtr net,
111                                   virDomainNetDefPtr iface);
112
113 static virNetworkDriverStatePtr driverState = NULL;
114
115 static virNetworkObjPtr
116 networkObjFromNetwork(virNetworkPtr net)
117 {
118     virNetworkDriverStatePtr driver = net->conn->networkPrivateData;
119     virNetworkObjPtr network;
120     char uuidstr[VIR_UUID_STRING_BUFLEN];
121
122     networkDriverLock(driver);
123     network = virNetworkFindByUUID(&driver->networks, net->uuid);
124     networkDriverUnlock(driver);
125
126     if (!network) {
127         virUUIDFormat(net->uuid, uuidstr);
128         virReportError(VIR_ERR_NO_NETWORK,
129                        _("no network with matching uuid '%s' (%s)"),
130                        uuidstr, net->name);
131     }
132
133     return network;
134 }
135
136 static char *
137 networkDnsmasqLeaseFileNameDefault(const char *netname)
138 {
139     char *leasefile;
140
141     ignore_value(virAsprintf(&leasefile, "%s/%s.leases",
142                              driverState->dnsmasqStateDir, netname));
143     return leasefile;
144 }
145
146 networkDnsmasqLeaseFileNameFunc networkDnsmasqLeaseFileName =
147     networkDnsmasqLeaseFileNameDefault;
148
149 static char *
150 networkDnsmasqConfigFileName(const char *netname)
151 {
152     char *conffile;
153
154     ignore_value(virAsprintf(&conffile, "%s/%s.conf",
155                              driverState->dnsmasqStateDir, netname));
156     return conffile;
157 }
158
159 static char *
160 networkRadvdPidfileBasename(const char *netname)
161 {
162     /* this is simple but we want to be sure it's consistently done */
163     char *pidfilebase;
164
165     ignore_value(virAsprintf(&pidfilebase, "%s-radvd", netname));
166     return pidfilebase;
167 }
168
169 static char *
170 networkRadvdConfigFileName(const char *netname)
171 {
172     char *configfile;
173
174     ignore_value(virAsprintf(&configfile, "%s/%s-radvd.conf",
175                              driverState->radvdStateDir, netname));
176     return configfile;
177 }
178
179 /* do needed cleanup steps and remove the network from the list */
180 static int
181 networkRemoveInactive(virNetworkDriverStatePtr driver,
182                       virNetworkObjPtr net)
183 {
184     char *leasefile = NULL;
185     char *radvdconfigfile = NULL;
186     char *configfile = NULL;
187     char *radvdpidbase = NULL;
188     char *statusfile = NULL;
189     dnsmasqContext *dctx = NULL;
190     virNetworkDefPtr def = virNetworkObjGetPersistentDef(net);
191
192     int ret = -1;
193
194     /* remove the (possibly) existing dnsmasq and radvd files */
195     if (!(dctx = dnsmasqContextNew(def->name,
196                                    driverState->dnsmasqStateDir))) {
197         goto cleanup;
198     }
199
200     if (!(leasefile = networkDnsmasqLeaseFileName(def->name)))
201         goto cleanup;
202
203     if (!(radvdconfigfile = networkRadvdConfigFileName(def->name)))
204         goto cleanup;
205
206     if (!(radvdpidbase = networkRadvdPidfileBasename(def->name)))
207         goto cleanup;
208
209     if (!(configfile = networkDnsmasqConfigFileName(def->name)))
210         goto cleanup;
211
212     if (!(statusfile
213           = virNetworkConfigFile(driverState->stateDir, def->name)))
214         goto cleanup;
215
216     /* dnsmasq */
217     dnsmasqDelete(dctx);
218     unlink(leasefile);
219     unlink(configfile);
220
221     /* radvd */
222     unlink(radvdconfigfile);
223     virPidFileDelete(driverState->pidDir, radvdpidbase);
224
225     /* remove status file */
226     unlink(statusfile);
227
228     /* remove the network definition */
229     virNetworkRemoveInactive(&driver->networks, net);
230
231     ret = 0;
232
233 cleanup:
234     VIR_FREE(leasefile);
235     VIR_FREE(configfile);
236     VIR_FREE(radvdconfigfile);
237     VIR_FREE(radvdpidbase);
238     VIR_FREE(statusfile);
239     dnsmasqContextFree(dctx);
240     return ret;
241 }
242
243 static char *
244 networkBridgeDummyNicName(const char *brname)
245 {
246     static const char dummyNicSuffix[] = "-nic";
247     char *nicname;
248
249     if (strlen(brname) + sizeof(dummyNicSuffix) > IFNAMSIZ) {
250         /* because the length of an ifname is limited to IFNAMSIZ-1
251          * (usually 15), and we're adding 4 more characters, we must
252          * truncate the original name to 11 to fit. In order to catch
253          * a possible numeric ending (eg virbr0, virbr1, etc), we grab
254          * the first 8 and last 3 characters of the string.
255          */
256         ignore_value(virAsprintf(&nicname, "%.*s%s%s",
257                                  /* space for last 3 chars + "-nic" + NULL */
258                                  (int)(IFNAMSIZ - (3 + sizeof(dummyNicSuffix))),
259                                  brname, brname + strlen(brname) - 3,
260                                  dummyNicSuffix));
261     } else {
262         ignore_value(virAsprintf(&nicname, "%s%s", brname, dummyNicSuffix));
263     }
264     return nicname;
265 }
266
267 static void
268 networkFindActiveConfigs(virNetworkDriverStatePtr driver)
269 {
270     size_t i;
271
272     for (i = 0; i < driver->networks.count; i++) {
273         virNetworkObjPtr obj = driver->networks.objs[i];
274
275         virNetworkObjLock(obj);
276
277         /* If bridge exists, then mark it active */
278         if (obj->def->bridge &&
279             virNetDevExists(obj->def->bridge) == 1) {
280             obj->active = 1;
281
282             /* Try and read dnsmasq/radvd pids if any */
283             if (obj->def->ips && (obj->def->nips > 0)) {
284                 char *radvdpidbase;
285
286                 ignore_value(virPidFileReadIfAlive(driverState->pidDir, obj->def->name,
287                                                    &obj->dnsmasqPid,
288                                                    dnsmasqCapsGetBinaryPath(driver->dnsmasqCaps)));
289
290                 if (!(radvdpidbase = networkRadvdPidfileBasename(obj->def->name)))
291                     goto cleanup;
292                 ignore_value(virPidFileReadIfAlive(driverState->pidDir, radvdpidbase,
293                                                    &obj->radvdPid, RADVD));
294                 VIR_FREE(radvdpidbase);
295             }
296         }
297
298     cleanup:
299         virNetworkObjUnlock(obj);
300     }
301
302     /* remove inactive transient networks */
303     i = 0;
304     while (i < driver->networks.count) {
305         virNetworkObjPtr obj = driver->networks.objs[i];
306         virNetworkObjLock(obj);
307
308         if (!obj->persistent && !obj->active) {
309             networkRemoveInactive(driver, obj);
310             continue;
311         }
312
313         virNetworkObjUnlock(obj);
314         i++;
315     }
316 }
317
318
319 static void
320 networkAutostartConfigs(virNetworkDriverStatePtr driver) {
321     size_t i;
322
323     for (i = 0; i < driver->networks.count; i++) {
324         virNetworkObjLock(driver->networks.objs[i]);
325         if (driver->networks.objs[i]->autostart &&
326             !virNetworkObjIsActive(driver->networks.objs[i])) {
327             if (networkStartNetwork(driver, driver->networks.objs[i]) < 0) {
328             /* failed to start but already logged */
329             }
330         }
331         virNetworkObjUnlock(driver->networks.objs[i]);
332     }
333 }
334
335 #if HAVE_FIREWALLD
336 static DBusHandlerResult
337 firewalld_dbus_filter_bridge(DBusConnection *connection ATTRIBUTE_UNUSED,
338                              DBusMessage *message, void *user_data) {
339     virNetworkDriverStatePtr _driverState = user_data;
340
341     if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS,
342                                "NameOwnerChanged") ||
343         dbus_message_is_signal(message, "org.fedoraproject.FirewallD1",
344                                "Reloaded"))
345     {
346         VIR_DEBUG("Reload in bridge_driver because of firewalld.");
347         networkReloadFirewallRules(_driverState);
348     }
349
350     return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
351 }
352 #endif
353
354 /**
355  * networkStateInitialize:
356  *
357  * Initialization function for the QEmu daemon
358  */
359 static int
360 networkStateInitialize(bool privileged,
361                        virStateInhibitCallback callback ATTRIBUTE_UNUSED,
362                        void *opaque ATTRIBUTE_UNUSED)
363 {
364     int ret = -1;
365     char *configdir = NULL;
366     char *rundir = NULL;
367 #ifdef HAVE_FIREWALLD
368     DBusConnection *sysbus = NULL;
369 #endif
370
371     if (VIR_ALLOC(driverState) < 0)
372         goto error;
373
374     if (virMutexInit(&driverState->lock) < 0) {
375         VIR_FREE(driverState);
376         goto error;
377     }
378     networkDriverLock(driverState);
379
380     /* configuration/state paths are one of
381      * ~/.config/libvirt/... (session/unprivileged)
382      * /etc/libvirt/... && /var/(run|lib)/libvirt/... (system/privileged).
383      *
384      * NB: The qemu driver puts its domain state in /var/run, and I
385      * think the network driver should have used /var/run too (instead
386      * of /var/lib), but it's been this way for a long time, and we
387      * probably shouldn't change it now.
388      */
389     if (privileged) {
390         if (VIR_STRDUP(driverState->networkConfigDir,
391                        SYSCONFDIR "/libvirt/qemu/networks") < 0 ||
392             VIR_STRDUP(driverState->networkAutostartDir,
393                        SYSCONFDIR "/libvirt/qemu/networks/autostart") < 0 ||
394             VIR_STRDUP(driverState->stateDir,
395                        LOCALSTATEDIR "/lib/libvirt/network") < 0 ||
396             VIR_STRDUP(driverState->pidDir,
397                        LOCALSTATEDIR "/run/libvirt/network") < 0 ||
398             VIR_STRDUP(driverState->dnsmasqStateDir,
399                        LOCALSTATEDIR "/lib/libvirt/dnsmasq") < 0 ||
400             VIR_STRDUP(driverState->radvdStateDir,
401                        LOCALSTATEDIR "/lib/libvirt/radvd") < 0)
402             goto error;
403     } else {
404         configdir = virGetUserConfigDirectory();
405         rundir = virGetUserRuntimeDirectory();
406         if (!(configdir && rundir))
407             goto error;
408
409         if ((virAsprintf(&driverState->networkConfigDir,
410                          "%s/qemu/networks", configdir) < 0) ||
411             (virAsprintf(&driverState->networkAutostartDir,
412                          "%s/qemu/networks/autostart", configdir) < 0) ||
413             (virAsprintf(&driverState->stateDir,
414                          "%s/network/lib", rundir) < 0) ||
415             (virAsprintf(&driverState->pidDir,
416                          "%s/network/run", rundir) < 0) ||
417             (virAsprintf(&driverState->dnsmasqStateDir,
418                          "%s/dnsmasq/lib", rundir) < 0) ||
419             (virAsprintf(&driverState->radvdStateDir,
420                          "%s/radvd/lib", rundir) < 0)) {
421             goto error;
422         }
423     }
424
425     /* if this fails now, it will be retried later with dnsmasqCapsRefresh() */
426     driverState->dnsmasqCaps = dnsmasqCapsNewFromBinary(DNSMASQ);
427
428     if (virNetworkLoadAllState(&driverState->networks,
429                                driverState->stateDir) < 0)
430         goto error;
431
432     if (virNetworkLoadAllConfigs(&driverState->networks,
433                                  driverState->networkConfigDir,
434                                  driverState->networkAutostartDir) < 0)
435         goto error;
436
437     networkFindActiveConfigs(driverState);
438     networkReloadFirewallRules(driverState);
439     networkRefreshDaemons(driverState);
440
441     networkDriverUnlock(driverState);
442
443 #ifdef HAVE_FIREWALLD
444     if (!(sysbus = virDBusGetSystemBus())) {
445         virErrorPtr err = virGetLastError();
446         VIR_WARN("DBus not available, disabling firewalld support "
447                  "in bridge_driver: %s", err->message);
448     } else {
449         /* add matches for
450          * NameOwnerChanged on org.freedesktop.DBus for firewalld start/stop
451          * Reloaded on org.fedoraproject.FirewallD1 for firewalld reload
452          */
453         dbus_bus_add_match(sysbus,
454                            "type='signal'"
455                            ",interface='"DBUS_INTERFACE_DBUS"'"
456                            ",member='NameOwnerChanged'"
457                            ",arg0='org.fedoraproject.FirewallD1'",
458                            NULL);
459         dbus_bus_add_match(sysbus,
460                            "type='signal'"
461                            ",interface='org.fedoraproject.FirewallD1'"
462                            ",member='Reloaded'",
463                            NULL);
464         dbus_connection_add_filter(sysbus, firewalld_dbus_filter_bridge,
465                                    driverState, NULL);
466     }
467 #endif
468
469     ret = 0;
470 cleanup:
471     VIR_FREE(configdir);
472     VIR_FREE(rundir);
473     return ret;
474
475 error:
476     if (driverState)
477         networkDriverUnlock(driverState);
478     networkStateCleanup();
479     goto cleanup;
480 }
481
482 /**
483  * networkStateAutoStart:
484  *
485  * Function to AutoStart the bridge configs
486  */
487 static void
488 networkStateAutoStart(void)
489 {
490     if (!driverState)
491         return;
492
493     networkDriverLock(driverState);
494     networkAutostartConfigs(driverState);
495     networkDriverUnlock(driverState);
496 }
497
498 /**
499  * networkStateReload:
500  *
501  * Function to restart the QEmu daemon, it will recheck the configuration
502  * files and update its state and the networking
503  */
504 static int
505 networkStateReload(void) {
506     if (!driverState)
507         return 0;
508
509     networkDriverLock(driverState);
510     virNetworkLoadAllState(&driverState->networks,
511                            driverState->stateDir);
512     virNetworkLoadAllConfigs(&driverState->networks,
513                              driverState->networkConfigDir,
514                              driverState->networkAutostartDir);
515     networkReloadFirewallRules(driverState);
516     networkRefreshDaemons(driverState);
517     networkAutostartConfigs(driverState);
518     networkDriverUnlock(driverState);
519     return 0;
520 }
521
522
523 /**
524  * networkStateCleanup:
525  *
526  * Shutdown the QEmu daemon, it will stop all active domains and networks
527  */
528 static int
529 networkStateCleanup(void) {
530     if (!driverState)
531         return -1;
532
533     networkDriverLock(driverState);
534
535     /* free inactive networks */
536     virNetworkObjListFree(&driverState->networks);
537
538     VIR_FREE(driverState->networkConfigDir);
539     VIR_FREE(driverState->networkAutostartDir);
540     VIR_FREE(driverState->stateDir);
541     VIR_FREE(driverState->pidDir);
542     VIR_FREE(driverState->dnsmasqStateDir);
543     VIR_FREE(driverState->radvdStateDir);
544
545     virObjectUnref(driverState->dnsmasqCaps);
546
547     networkDriverUnlock(driverState);
548     virMutexDestroy(&driverState->lock);
549
550     VIR_FREE(driverState);
551
552     return 0;
553 }
554
555
556 /* networkKillDaemon:
557  *
558  * kill the specified pid/name, and wait a bit to make sure it's dead.
559  */
560 static int
561 networkKillDaemon(pid_t pid, const char *daemonName, const char *networkName)
562 {
563     size_t i;
564     int ret = -1;
565     const char *signame = "TERM";
566
567     /* send SIGTERM, then wait up to 3 seconds for the process to
568      * disappear, send SIGKILL, then wait for up to another 2
569      * seconds. If that fails, log a warning and continue, hoping
570      * for the best.
571      */
572     for (i = 0; i < 25; i++) {
573         int signum = 0;
574         if (i == 0)
575             signum = SIGTERM;
576         else if (i == 15) {
577             signum = SIGKILL;
578             signame = "KILL";
579         }
580         if (kill(pid, signum) < 0) {
581             if (errno == ESRCH) {
582                 ret = 0;
583             } else {
584                 char ebuf[1024];
585                 VIR_WARN("Failed to terminate %s process %d "
586                          "for network '%s' with SIG%s: %s",
587                          daemonName, pid, networkName, signame,
588                          virStrerror(errno, ebuf, sizeof(ebuf)));
589             }
590             goto cleanup;
591         }
592         /* NB: since networks have no reference count like
593          * domains, there is no safe way to unlock the network
594          * object temporarily, and so we can't follow the
595          * procedure used by the qemu driver of 1) unlock driver
596          * 2) sleep, 3) add ref to object 4) unlock object, 5)
597          * re-lock driver, 6) re-lock object. We may need to add
598          * that functionality eventually, but for now this
599          * function is rarely used and, at worst, leaving the
600          * network driver locked during this loop of sleeps will
601          * have the effect of holding up any other thread trying
602          * to make modifications to a network for up to 5 seconds;
603          * since modifications to networks are much less common
604          * than modifications to domains, this seems a reasonable
605          * tradeoff in exchange for less code disruption.
606          */
607         usleep(20 * 1000);
608     }
609     VIR_WARN("Timed out waiting after SIG%s to %s process %d "
610              "(network '%s')",
611              signame, daemonName, pid, networkName);
612 cleanup:
613     return ret;
614 }
615
616     /* the following does not build a file, it builds a list
617      * which is later saved into a file
618      */
619
620 static int
621 networkBuildDnsmasqDhcpHostsList(dnsmasqContext *dctx,
622                                  virNetworkIpDefPtr ipdef)
623 {
624     size_t i;
625     bool ipv6 = false;
626
627     if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6))
628         ipv6 = true;
629     for (i = 0; i < ipdef->nhosts; i++) {
630         virNetworkDHCPHostDefPtr host = &(ipdef->hosts[i]);
631         if (VIR_SOCKET_ADDR_VALID(&host->ip))
632             if (dnsmasqAddDhcpHost(dctx, host->mac, &host->ip,
633                                    host->name, host->id, ipv6) < 0)
634                 return -1;
635     }
636
637     return 0;
638 }
639
640 static int
641 networkBuildDnsmasqHostsList(dnsmasqContext *dctx,
642                              virNetworkDNSDefPtr dnsdef)
643 {
644     size_t i, j;
645
646     if (dnsdef) {
647         for (i = 0; i < dnsdef->nhosts; i++) {
648             virNetworkDNSHostDefPtr host = &(dnsdef->hosts[i]);
649             if (VIR_SOCKET_ADDR_VALID(&host->ip)) {
650                 for (j = 0; j < host->nnames; j++)
651                     if (dnsmasqAddHost(dctx, &host->ip, host->names[j]) < 0)
652                         return -1;
653             }
654         }
655     }
656
657     return 0;
658 }
659
660
661 int
662 networkDnsmasqConfContents(virNetworkObjPtr network,
663                            const char *pidfile,
664                            char **configstr,
665                            dnsmasqContext *dctx,
666                            dnsmasqCapsPtr caps ATTRIBUTE_UNUSED)
667 {
668     virBuffer configbuf = VIR_BUFFER_INITIALIZER;
669     int r, ret = -1;
670     int nbleases = 0;
671     size_t i;
672     char *record = NULL;
673     char *recordPort = NULL;
674     char *recordWeight = NULL;
675     char *recordPriority = NULL;
676     virNetworkDNSDefPtr dns = &network->def->dns;
677     virNetworkIpDefPtr tmpipdef, ipdef, ipv4def, ipv6def;
678     bool ipv6SLAAC;
679
680     *configstr = NULL;
681
682     /*
683      * All dnsmasq parameters are put into a configuration file, except the
684      * command line --conf-file=parameter which specifies the location of
685      * configuration file.
686      *
687      * All dnsmasq conf-file parameters must be specified as "foo=bar"
688      * as oppose to "--foo bar" which was acceptable on the command line.
689      */
690
691     /*
692      * Needed to ensure dnsmasq uses same algorithm for processing
693      * multiple namedriver entries in /etc/resolv.conf as GLibC.
694      */
695
696     /* create dnsmasq config file appropriate for this network */
697     virBufferAsprintf(&configbuf,
698                       "##WARNING:  THIS IS AN AUTO-GENERATED FILE. "
699                       "CHANGES TO IT ARE LIKELY TO BE\n"
700                       "##OVERWRITTEN AND LOST.  Changes to this "
701                       "configuration should be made using:\n"
702                       "##    virsh net-edit %s\n"
703                       "## or other application using the libvirt API.\n"
704                       "##\n## dnsmasq conf file created by libvirt\n"
705                       "strict-order\n",
706                       network->def->name);
707
708     if (!network->def->dns.forwardPlainNames)
709         virBufferAddLit(&configbuf, "domain-needed\n");
710
711     if (network->def->domain) {
712         virBufferAsprintf(&configbuf,
713                           "domain=%s\n"
714                           "expand-hosts\n",
715                           network->def->domain);
716     }
717
718     if (network->def->domain || !network->def->dns.forwardPlainNames) {
719         /* need to specify local even if no domain specified, unless
720          * the config says we should forward "plain" names (i.e. not
721          * fully qualified, no '.' characters)
722          */
723         virBufferAsprintf(&configbuf,
724                           "local=/%s/\n",
725                           network->def->domain ? network->def->domain : "");
726     }
727
728     if (pidfile)
729         virBufferAsprintf(&configbuf, "pid-file=%s\n", pidfile);
730
731     /* dnsmasq will *always* listen on localhost unless told otherwise */
732     virBufferAddLit(&configbuf, "except-interface=lo\n");
733
734     if (dnsmasqCapsGet(caps, DNSMASQ_CAPS_BIND_DYNAMIC)) {
735         /* using --bind-dynamic with only --interface (no
736          * --listen-address) prevents dnsmasq from responding to dns
737          * queries that arrive on some interface other than our bridge
738          * interface (in other words, requests originating somewhere
739          * other than one of the virtual guests connected directly to
740          * this network). This was added in response to CVE 2012-3411.
741          */
742         virBufferAsprintf(&configbuf,
743                           "bind-dynamic\n"
744                           "interface=%s\n",
745                           network->def->bridge);
746     } else {
747         virBufferAddLit(&configbuf, "bind-interfaces\n");
748         /*
749          * --interface does not actually work with dnsmasq < 2.47,
750          * due to DAD for ipv6 addresses on the interface.
751          *
752          * virCommandAddArgList(cmd, "--interface", network->def->bridge, NULL);
753          *
754          * So listen on all defined IPv[46] addresses
755          */
756         for (i = 0;
757              (tmpipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, i));
758              i++) {
759             char *ipaddr = virSocketAddrFormat(&tmpipdef->address);
760
761             if (!ipaddr)
762                 goto cleanup;
763
764             /* also part of CVE 2012-3411 - if the host's version of
765              * dnsmasq doesn't have bind-dynamic, only allow listening on
766              * private/local IP addresses (see RFC1918/RFC3484/RFC4193)
767              */
768             if (!dnsmasqCapsGet(caps, DNSMASQ_CAPS_BINDTODEVICE) &&
769                 !virSocketAddrIsPrivate(&tmpipdef->address)) {
770                 unsigned long version = dnsmasqCapsGetVersion(caps);
771
772                 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
773                                _("Publicly routable address %s is prohibited. "
774                                  "The version of dnsmasq on this host (%d.%d) "
775                                  "doesn't support the bind-dynamic option or "
776                                  "use SO_BINDTODEVICE on listening sockets, "
777                                  "one of which is required for safe operation "
778                                  "on a publicly routable subnet "
779                                  "(see CVE-2012-3411). You must either "
780                                  "upgrade dnsmasq, or use a private/local "
781                                  "subnet range for this network "
782                                  "(as described in RFC1918/RFC3484/RFC4193)."),
783                                ipaddr, (int)version / 1000000,
784                                (int)(version % 1000000) / 1000);
785                 goto cleanup;
786             }
787             virBufferAsprintf(&configbuf, "listen-address=%s\n", ipaddr);
788             VIR_FREE(ipaddr);
789         }
790     }
791
792     /* If this is an isolated network, set the default route option
793      * (3) to be empty to avoid setting a default route that's
794      * guaranteed to not work, and set no-resolv so that no dns
795      * requests are forwarded on to the dns server listed in the
796      * host's /etc/resolv.conf (since this could be used as a channel
797      * to build a connection to the outside).
798      */
799     if (network->def->forward.type == VIR_NETWORK_FORWARD_NONE) {
800         virBufferAddLit(&configbuf, "dhcp-option=3\n"
801                         "no-resolv\n");
802     }
803
804     for (i = 0; i < dns->ntxts; i++) {
805         virBufferAsprintf(&configbuf, "txt-record=%s,%s\n",
806                           dns->txts[i].name,
807                           dns->txts[i].value);
808     }
809
810     for (i = 0; i < dns->nsrvs; i++) {
811         if (dns->srvs[i].service && dns->srvs[i].protocol) {
812             if (dns->srvs[i].port &&
813                 virAsprintf(&recordPort, "%d", dns->srvs[i].port) < 0)
814                 goto cleanup;
815             if (dns->srvs[i].priority &&
816                 virAsprintf(&recordPriority, "%d", dns->srvs[i].priority) < 0)
817                 goto cleanup;
818             if (dns->srvs[i].weight &&
819                 virAsprintf(&recordWeight, "%d", dns->srvs[i].weight) < 0)
820                 goto cleanup;
821
822             if (virAsprintf(&record, "%s.%s.%s,%s,%s,%s,%s",
823                             dns->srvs[i].service,
824                             dns->srvs[i].protocol,
825                             dns->srvs[i].domain ? dns->srvs[i].domain : "",
826                             dns->srvs[i].target ? dns->srvs[i].target : "",
827                             recordPort           ? recordPort           : "",
828                             recordPriority       ? recordPriority       : "",
829                             recordWeight         ? recordWeight         : "") < 0)
830                 goto cleanup;
831
832             virBufferAsprintf(&configbuf, "srv-host=%s\n", record);
833             VIR_FREE(record);
834             VIR_FREE(recordPort);
835             VIR_FREE(recordWeight);
836             VIR_FREE(recordPriority);
837         }
838     }
839
840     /* Find the first dhcp for both IPv4 and IPv6 */
841     for (i = 0, ipv4def = NULL, ipv6def = NULL, ipv6SLAAC = false;
842          (ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, i));
843          i++) {
844         if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET)) {
845             if (ipdef->nranges || ipdef->nhosts) {
846                 if (ipv4def) {
847                     virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
848                                    _("For IPv4, multiple DHCP definitions "
849                                      "cannot be specified."));
850                     goto cleanup;
851                 } else {
852                     ipv4def = ipdef;
853                 }
854             }
855         }
856         if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6)) {
857             if (ipdef->nranges || ipdef->nhosts) {
858                 if (!DNSMASQ_DHCPv6_SUPPORT(caps)) {
859                     unsigned long version = dnsmasqCapsGetVersion(caps);
860                     virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
861                                    _("The version of dnsmasq on this host "
862                                      "(%d.%d) doesn't adequately support "
863                                      "IPv6 dhcp range or dhcp host "
864                                      "specification. Version %d.%d or later "
865                                      "is required."),
866                                    (int)version / 1000000,
867                                    (int)(version % 1000000) / 1000,
868                                    DNSMASQ_DHCPv6_MAJOR_REQD,
869                                    DNSMASQ_DHCPv6_MINOR_REQD);
870                     goto cleanup;
871                 }
872                 if (ipv6def) {
873                     virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
874                                    _("For IPv6, multiple DHCP definitions "
875                                      "cannot be specified."));
876                     goto cleanup;
877                 } else {
878                     ipv6def = ipdef;
879                 }
880             } else {
881                 ipv6SLAAC = true;
882             }
883         }
884     }
885
886     if (ipv6def && ipv6SLAAC) {
887         VIR_WARN("For IPv6, when DHCP is specified for one address, then "
888                  "state-full Router Advertising will occur.  The additional "
889                  "IPv6 addresses specified require manually configured guest "
890                  "network to work properly since both state-full (DHCP) "
891                  "and state-less (SLAAC) addressing are not supported "
892                  "on the same network interface.");
893     }
894
895     ipdef = ipv4def ? ipv4def : ipv6def;
896
897     while (ipdef) {
898         for (r = 0; r < ipdef->nranges; r++) {
899             char *saddr = virSocketAddrFormat(&ipdef->ranges[r].start);
900             if (!saddr)
901                 goto cleanup;
902             char *eaddr = virSocketAddrFormat(&ipdef->ranges[r].end);
903             if (!eaddr) {
904                 VIR_FREE(saddr);
905                 goto cleanup;
906             }
907             virBufferAsprintf(&configbuf, "dhcp-range=%s,%s\n",
908                               saddr, eaddr);
909             VIR_FREE(saddr);
910             VIR_FREE(eaddr);
911             nbleases += virSocketAddrGetRange(&ipdef->ranges[r].start,
912                                               &ipdef->ranges[r].end);
913         }
914
915         /*
916          * For static-only DHCP, i.e. with no range but at least one
917          * host element, we have to add a special --dhcp-range option
918          * to enable the service in dnsmasq. (this is for dhcp-hosts=
919          * support)
920          */
921         if (!ipdef->nranges && ipdef->nhosts) {
922             char *bridgeaddr = virSocketAddrFormat(&ipdef->address);
923             if (!bridgeaddr)
924                 goto cleanup;
925             virBufferAsprintf(&configbuf, "dhcp-range=%s,static\n", bridgeaddr);
926             VIR_FREE(bridgeaddr);
927         }
928
929         if (networkBuildDnsmasqDhcpHostsList(dctx, ipdef) < 0)
930             goto cleanup;
931
932         /* Note: the following is IPv4 only */
933         if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET)) {
934             if (ipdef->nranges || ipdef->nhosts)
935                 virBufferAddLit(&configbuf, "dhcp-no-override\n");
936
937             if (ipdef->tftproot) {
938                 virBufferAddLit(&configbuf, "enable-tftp\n");
939                 virBufferAsprintf(&configbuf, "tftp-root=%s\n", ipdef->tftproot);
940             }
941
942             if (ipdef->bootfile) {
943                 if (VIR_SOCKET_ADDR_VALID(&ipdef->bootserver)) {
944                     char *bootserver = virSocketAddrFormat(&ipdef->bootserver);
945
946                     if (!bootserver)
947                         goto cleanup;
948                     virBufferAsprintf(&configbuf, "dhcp-boot=%s%s%s\n",
949                                       ipdef->bootfile, ",,", bootserver);
950                     VIR_FREE(bootserver);
951                 } else {
952                     virBufferAsprintf(&configbuf, "dhcp-boot=%s\n", ipdef->bootfile);
953                 }
954             }
955         }
956         ipdef = (ipdef == ipv6def) ? NULL : ipv6def;
957     }
958
959     if (nbleases > 0) {
960         char *leasefile = networkDnsmasqLeaseFileName(network->def->name);
961         if (!leasefile)
962             goto cleanup;
963         virBufferAsprintf(&configbuf, "dhcp-leasefile=%s\n", leasefile);
964         VIR_FREE(leasefile);
965         virBufferAsprintf(&configbuf, "dhcp-lease-max=%d\n", nbleases);
966     }
967
968     /* this is done once per interface */
969     if (networkBuildDnsmasqHostsList(dctx, dns) < 0)
970         goto cleanup;
971
972     /* Even if there are currently no static hosts, if we're
973      * listening for DHCP, we should write a 0-length hosts
974      * file to allow for runtime additions.
975      */
976     if (ipv4def || ipv6def)
977         virBufferAsprintf(&configbuf, "dhcp-hostsfile=%s\n",
978                           dctx->hostsfile->path);
979
980     /* Likewise, always create this file and put it on the
981      * commandline, to allow for runtime additions.
982      */
983     virBufferAsprintf(&configbuf, "addn-hosts=%s\n",
984                       dctx->addnhostsfile->path);
985
986     /* Are we doing RA instead of radvd? */
987     if (DNSMASQ_RA_SUPPORT(caps)) {
988         if (ipv6def)
989             virBufferAddLit(&configbuf, "enable-ra\n");
990         else {
991             for (i = 0;
992                  (ipdef = virNetworkDefGetIpByIndex(network->def, AF_INET6, i));
993                  i++) {
994                 if (!(ipdef->nranges || ipdef->nhosts)) {
995                     char *bridgeaddr = virSocketAddrFormat(&ipdef->address);
996                     if (!bridgeaddr)
997                         goto cleanup;
998                     virBufferAsprintf(&configbuf,
999                                       "dhcp-range=%s,ra-only\n", bridgeaddr);
1000                     VIR_FREE(bridgeaddr);
1001                 }
1002             }
1003         }
1004     }
1005
1006     if (!(*configstr = virBufferContentAndReset(&configbuf)))
1007         goto cleanup;
1008
1009     ret = 0;
1010
1011 cleanup:
1012     virBufferFreeAndReset(&configbuf);
1013     VIR_FREE(record);
1014     VIR_FREE(recordPort);
1015     VIR_FREE(recordWeight);
1016     VIR_FREE(recordPriority);
1017     return ret;
1018 }
1019
1020 /* build the dnsmasq command line */
1021 static int ATTRIBUTE_NONNULL(2)
1022 networkBuildDhcpDaemonCommandLine(virNetworkObjPtr network,
1023                                   virCommandPtr *cmdout,
1024                                   char *pidfile, dnsmasqContext *dctx,
1025                                   dnsmasqCapsPtr caps)
1026 {
1027     virCommandPtr cmd = NULL;
1028     int ret = -1;
1029     char *configfile = NULL;
1030     char *configstr = NULL;
1031
1032     network->dnsmasqPid = -1;
1033
1034     if (networkDnsmasqConfContents(network, pidfile, &configstr, dctx, caps) < 0)
1035         goto cleanup;
1036     if (!configstr)
1037         goto cleanup;
1038
1039     /* construct the filename */
1040     if (!(configfile = networkDnsmasqConfigFileName(network->def->name)))
1041         goto cleanup;
1042
1043     /* Write the file */
1044     if (virFileWriteStr(configfile, configstr, 0600) < 0) {
1045         virReportSystemError(errno,
1046                          _("couldn't write dnsmasq config file '%s'"),
1047                          configfile);
1048         goto cleanup;
1049     }
1050
1051     cmd = virCommandNew(dnsmasqCapsGetBinaryPath(caps));
1052     virCommandAddArgFormat(cmd, "--conf-file=%s", configfile);
1053     *cmdout = cmd;
1054     ret = 0;
1055 cleanup:
1056     return ret;
1057 }
1058
1059 static int
1060 networkStartDhcpDaemon(virNetworkDriverStatePtr driver,
1061                        virNetworkObjPtr network)
1062 {
1063     virCommandPtr cmd = NULL;
1064     char *pidfile = NULL;
1065     int ret = -1;
1066     dnsmasqContext *dctx = NULL;
1067
1068     if (!virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, 0)) {
1069         /* no IP addresses, so we don't need to run */
1070         ret = 0;
1071         goto cleanup;
1072     }
1073
1074     if (virFileMakePath(driverState->pidDir) < 0) {
1075         virReportSystemError(errno,
1076                              _("cannot create directory %s"),
1077                              driverState->pidDir);
1078         goto cleanup;
1079     }
1080     if (virFileMakePath(driverState->stateDir) < 0) {
1081         virReportSystemError(errno,
1082                              _("cannot create directory %s"),
1083                              driverState->stateDir);
1084         goto cleanup;
1085     }
1086
1087     if (!(pidfile = virPidFileBuildPath(driverState->pidDir,
1088                                         network->def->name)))
1089         goto cleanup;
1090
1091     if (virFileMakePath(driverState->dnsmasqStateDir) < 0) {
1092         virReportSystemError(errno,
1093                              _("cannot create directory %s"),
1094                              driverState->dnsmasqStateDir);
1095         goto cleanup;
1096     }
1097
1098     dctx = dnsmasqContextNew(network->def->name, driverState->dnsmasqStateDir);
1099     if (dctx == NULL)
1100         goto cleanup;
1101
1102     dnsmasqCapsRefresh(&driver->dnsmasqCaps, false);
1103
1104     ret = networkBuildDhcpDaemonCommandLine(network, &cmd, pidfile,
1105                                             dctx, driver->dnsmasqCaps);
1106     if (ret < 0)
1107         goto cleanup;
1108
1109     ret = dnsmasqSave(dctx);
1110     if (ret < 0)
1111         goto cleanup;
1112
1113     ret = virCommandRun(cmd, NULL);
1114     if (ret < 0) {
1115         goto cleanup;
1116     }
1117
1118     /*
1119      * There really is no race here - when dnsmasq daemonizes, its
1120      * leader process stays around until its child has actually
1121      * written its pidfile. So by time virCommandRun exits it has
1122      * waitpid'd and guaranteed the proess has started and written a
1123      * pid
1124      */
1125
1126     ret = virPidFileRead(driverState->pidDir, network->def->name,
1127                          &network->dnsmasqPid);
1128     if (ret < 0)
1129         goto cleanup;
1130
1131     ret = 0;
1132 cleanup:
1133     VIR_FREE(pidfile);
1134     virCommandFree(cmd);
1135     dnsmasqContextFree(dctx);
1136     return ret;
1137 }
1138
1139 /* networkRefreshDhcpDaemon:
1140  *  Update dnsmasq config files, then send a SIGHUP so that it rereads
1141  *  them.   This only works for the dhcp-hostsfile and the
1142  *  addn-hosts file.
1143  *
1144  *  Returns 0 on success, -1 on failure.
1145  */
1146 static int
1147 networkRefreshDhcpDaemon(virNetworkDriverStatePtr driver,
1148                          virNetworkObjPtr network)
1149 {
1150     int ret = -1;
1151     size_t i;
1152     virNetworkIpDefPtr ipdef, ipv4def, ipv6def;
1153     dnsmasqContext *dctx = NULL;
1154
1155     /* if no IP addresses specified, nothing to do */
1156     if (!virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, 0))
1157         return 0;
1158
1159     /* if there's no running dnsmasq, just start it */
1160     if (network->dnsmasqPid <= 0 || (kill(network->dnsmasqPid, 0) < 0))
1161         return networkStartDhcpDaemon(driver, network);
1162
1163     VIR_INFO("Refreshing dnsmasq for network %s", network->def->bridge);
1164     if (!(dctx = dnsmasqContextNew(network->def->name,
1165                                    driverState->dnsmasqStateDir))) {
1166         goto cleanup;
1167     }
1168
1169     /* Look for first IPv4 address that has dhcp defined.
1170      * We only support dhcp-host config on one IPv4 subnetwork
1171      * and on one IPv6 subnetwork.
1172      */
1173     ipv4def = NULL;
1174     for (i = 0;
1175          (ipdef = virNetworkDefGetIpByIndex(network->def, AF_INET, i));
1176          i++) {
1177         if (!ipv4def && (ipdef->nranges || ipdef->nhosts))
1178             ipv4def = ipdef;
1179     }
1180
1181     ipv6def = NULL;
1182     for (i = 0;
1183          (ipdef = virNetworkDefGetIpByIndex(network->def, AF_INET6, i));
1184          i++) {
1185         if (!ipv6def && (ipdef->nranges || ipdef->nhosts))
1186             ipv6def = ipdef;
1187     }
1188
1189     if (ipv4def && (networkBuildDnsmasqDhcpHostsList(dctx, ipv4def) < 0))
1190            goto cleanup;
1191
1192     if (ipv6def && (networkBuildDnsmasqDhcpHostsList(dctx, ipv6def) < 0))
1193            goto cleanup;
1194
1195     if (networkBuildDnsmasqHostsList(dctx, &network->def->dns) < 0)
1196        goto cleanup;
1197
1198     if ((ret = dnsmasqSave(dctx)) < 0)
1199         goto cleanup;
1200
1201     ret = kill(network->dnsmasqPid, SIGHUP);
1202 cleanup:
1203     dnsmasqContextFree(dctx);
1204     return ret;
1205 }
1206
1207 /* networkRestartDhcpDaemon:
1208  *
1209  * kill and restart dnsmasq, in order to update any config that is on
1210  * the dnsmasq commandline (and any placed in separate config files).
1211  *
1212  *  Returns 0 on success, -1 on failure.
1213  */
1214 static int
1215 networkRestartDhcpDaemon(virNetworkDriverStatePtr driver,
1216                          virNetworkObjPtr network)
1217 {
1218     /* if there is a running dnsmasq, kill it */
1219     if (network->dnsmasqPid > 0) {
1220         networkKillDaemon(network->dnsmasqPid, "dnsmasq",
1221                           network->def->name);
1222         network->dnsmasqPid = -1;
1223     }
1224     /* now start dnsmasq if it should be started */
1225     return networkStartDhcpDaemon(driver, network);
1226 }
1227
1228 static char radvd1[] = "  AdvOtherConfigFlag off;\n\n";
1229 static char radvd2[] = "    AdvAutonomous off;\n";
1230 static char radvd3[] = "    AdvOnLink on;\n"
1231                        "    AdvAutonomous on;\n"
1232                        "    AdvRouterAddr off;\n";
1233
1234 static int
1235 networkRadvdConfContents(virNetworkObjPtr network, char **configstr)
1236 {
1237     virBuffer configbuf = VIR_BUFFER_INITIALIZER;
1238     int ret = -1;
1239     size_t i;
1240     virNetworkIpDefPtr ipdef;
1241     bool v6present = false, dhcp6 = false;
1242
1243     *configstr = NULL;
1244
1245     /* Check if DHCPv6 is needed */
1246     for (i = 0;
1247          (ipdef = virNetworkDefGetIpByIndex(network->def, AF_INET6, i));
1248          i++) {
1249         v6present = true;
1250         if (ipdef->nranges || ipdef->nhosts) {
1251             dhcp6 = true;
1252             break;
1253         }
1254     }
1255
1256     /* If there are no IPv6 addresses, then we are done */
1257     if (!v6present) {
1258         ret = 0;
1259         goto cleanup;
1260     }
1261
1262     /* create radvd config file appropriate for this network;
1263      * IgnoreIfMissing allows radvd to start even when the bridge is down
1264      */
1265     virBufferAsprintf(&configbuf, "interface %s\n"
1266                       "{\n"
1267                       "  AdvSendAdvert on;\n"
1268                       "  IgnoreIfMissing on;\n"
1269                       "  AdvManagedFlag %s;\n"
1270                       "%s",
1271                       network->def->bridge,
1272                       dhcp6 ? "on" : "off",
1273                       dhcp6 ? "\n" : radvd1);
1274
1275     /* add a section for each IPv6 address in the config */
1276     for (i = 0;
1277          (ipdef = virNetworkDefGetIpByIndex(network->def, AF_INET6, i));
1278          i++) {
1279         int prefix;
1280         char *netaddr;
1281
1282         prefix = virNetworkIpDefPrefix(ipdef);
1283         if (prefix < 0) {
1284             virReportError(VIR_ERR_INTERNAL_ERROR,
1285                            _("bridge '%s' has an invalid prefix"),
1286                            network->def->bridge);
1287             goto cleanup;
1288         }
1289         if (!(netaddr = virSocketAddrFormat(&ipdef->address)))
1290             goto cleanup;
1291         virBufferAsprintf(&configbuf,
1292                           "  prefix %s/%d\n"
1293                           "  {\n%s  };\n",
1294                           netaddr, prefix,
1295                           dhcp6 ? radvd2 : radvd3);
1296         VIR_FREE(netaddr);
1297     }
1298
1299     /* only create the string if we found at least one IPv6 address */
1300     if (v6present) {
1301         virBufferAddLit(&configbuf, "};\n");
1302
1303         if (virBufferError(&configbuf)) {
1304             virReportOOMError();
1305             goto cleanup;
1306         }
1307         if (!(*configstr = virBufferContentAndReset(&configbuf))) {
1308             virReportOOMError();
1309             goto cleanup;
1310         }
1311     }
1312
1313     ret = 0;
1314 cleanup:
1315     virBufferFreeAndReset(&configbuf);
1316     return ret;
1317 }
1318
1319 /* write file and return it's name (which must be freed by caller) */
1320 static int
1321 networkRadvdConfWrite(virNetworkObjPtr network, char **configFile)
1322 {
1323     int ret = -1;
1324     char *configStr = NULL;
1325     char *myConfigFile = NULL;
1326
1327     if (!configFile)
1328         configFile = &myConfigFile;
1329
1330     *configFile = NULL;
1331
1332     if (networkRadvdConfContents(network, &configStr) < 0)
1333         goto cleanup;
1334
1335     if (!configStr) {
1336         ret = 0;
1337         goto cleanup;
1338     }
1339
1340     /* construct the filename */
1341     if (!(*configFile = networkRadvdConfigFileName(network->def->name)))
1342         goto cleanup;
1343     /* write the file */
1344     if (virFileWriteStr(*configFile, configStr, 0600) < 0) {
1345         virReportSystemError(errno,
1346                              _("couldn't write radvd config file '%s'"),
1347                              *configFile);
1348         goto cleanup;
1349     }
1350
1351     ret = 0;
1352 cleanup:
1353     VIR_FREE(configStr);
1354     VIR_FREE(myConfigFile);
1355     return ret;
1356 }
1357
1358 static int
1359 networkStartRadvd(virNetworkDriverStatePtr driver ATTRIBUTE_UNUSED,
1360                         virNetworkObjPtr network)
1361 {
1362     char *pidfile = NULL;
1363     char *radvdpidbase = NULL;
1364     char *configfile = NULL;
1365     virCommandPtr cmd = NULL;
1366     int ret = -1;
1367
1368     network->radvdPid = -1;
1369
1370     /* Is dnsmasq handling RA? */
1371    if (DNSMASQ_RA_SUPPORT(driver->dnsmasqCaps)) {
1372         ret = 0;
1373         goto cleanup;
1374     }
1375
1376     if (!virNetworkDefGetIpByIndex(network->def, AF_INET6, 0)) {
1377         /* no IPv6 addresses, so we don't need to run radvd */
1378         ret = 0;
1379         goto cleanup;
1380     }
1381
1382     if (!virFileIsExecutable(RADVD)) {
1383         virReportSystemError(errno,
1384                              _("Cannot find %s - "
1385                                "Possibly the package isn't installed"),
1386                              RADVD);
1387         goto cleanup;
1388     }
1389
1390     if (virFileMakePath(driverState->pidDir) < 0) {
1391         virReportSystemError(errno,
1392                              _("cannot create directory %s"),
1393                              driverState->pidDir);
1394         goto cleanup;
1395     }
1396     if (virFileMakePath(driverState->radvdStateDir) < 0) {
1397         virReportSystemError(errno,
1398                              _("cannot create directory %s"),
1399                              driverState->radvdStateDir);
1400         goto cleanup;
1401     }
1402
1403     /* construct pidfile name */
1404     if (!(radvdpidbase = networkRadvdPidfileBasename(network->def->name)))
1405         goto cleanup;
1406     if (!(pidfile = virPidFileBuildPath(driverState->pidDir, radvdpidbase)))
1407         goto cleanup;
1408
1409     if (networkRadvdConfWrite(network, &configfile) < 0)
1410         goto cleanup;
1411
1412     /* prevent radvd from daemonizing itself with "--debug 1", and use
1413      * a dummy pidfile name - virCommand will create the pidfile we
1414      * want to use (this is necessary because radvd's internal
1415      * daemonization and pidfile creation causes a race, and the
1416      * virPidFileRead() below will fail if we use them).
1417      * Unfortunately, it isn't possible to tell radvd to not create
1418      * its own pidfile, so we just let it do so, with a slightly
1419      * different name. Unused, but harmless.
1420      */
1421     cmd = virCommandNewArgList(RADVD, "--debug", "1",
1422                                "--config", configfile,
1423                                "--pidfile", NULL);
1424     virCommandAddArgFormat(cmd, "%s-bin", pidfile);
1425
1426     virCommandSetPidFile(cmd, pidfile);
1427     virCommandDaemonize(cmd);
1428
1429     if (virCommandRun(cmd, NULL) < 0)
1430         goto cleanup;
1431
1432     if (virPidFileRead(driverState->pidDir, radvdpidbase, &network->radvdPid) < 0)
1433         goto cleanup;
1434
1435     ret = 0;
1436 cleanup:
1437     virCommandFree(cmd);
1438     VIR_FREE(configfile);
1439     VIR_FREE(radvdpidbase);
1440     VIR_FREE(pidfile);
1441     return ret;
1442 }
1443
1444 static int
1445 networkRefreshRadvd(virNetworkDriverStatePtr driver ATTRIBUTE_UNUSED,
1446                     virNetworkObjPtr network)
1447 {
1448     char *radvdpidbase;
1449
1450     /* Is dnsmasq handling RA? */
1451     if (DNSMASQ_RA_SUPPORT(driver->dnsmasqCaps)) {
1452         if (network->radvdPid <= 0)
1453             return 0;
1454         /* radvd should not be running but in case it is */
1455         if ((networkKillDaemon(network->radvdPid, "radvd",
1456                                network->def->name) >= 0) &&
1457             ((radvdpidbase = networkRadvdPidfileBasename(network->def->name))
1458              != NULL)) {
1459             virPidFileDelete(driverState->pidDir, radvdpidbase);
1460             VIR_FREE(radvdpidbase);
1461         }
1462         network->radvdPid = -1;
1463         return 0;
1464     }
1465
1466     /* if there's no running radvd, just start it */
1467     if (network->radvdPid <= 0 || (kill(network->radvdPid, 0) < 0))
1468         return networkStartRadvd(driver, network);
1469
1470     if (!virNetworkDefGetIpByIndex(network->def, AF_INET6, 0)) {
1471         /* no IPv6 addresses, so we don't need to run radvd */
1472         return 0;
1473     }
1474
1475     if (networkRadvdConfWrite(network, NULL) < 0)
1476         return -1;
1477
1478     return kill(network->radvdPid, SIGHUP);
1479 }
1480
1481 #if 0
1482 /* currently unused, so it causes a build error unless we #if it out */
1483 static int
1484 networkRestartRadvd(virNetworkDriverStatePtr driver,
1485                     virNetworkObjPtr network)
1486 {
1487     char *radvdpidbase;
1488
1489     /* if there is a running radvd, kill it */
1490     if (network->radvdPid > 0) {
1491         /* essentially ignore errors from the following two functions,
1492          * since there's really no better recovery to be done than to
1493          * just push ahead (and that may be exactly what's needed).
1494          */
1495         if ((networkKillDaemon(network->radvdPid, "radvd",
1496                                network->def->name) >= 0) &&
1497             ((radvdpidbase = networkRadvdPidfileBasename(network->def->name))
1498              != NULL)) {
1499             virPidFileDelete(driverState->pidDir, radvdpidbase);
1500             VIR_FREE(radvdpidbase);
1501         }
1502         network->radvdPid = -1;
1503     }
1504     /* now start radvd if it should be started */
1505     return networkStartRadvd(network);
1506 }
1507 #endif /* #if 0 */
1508
1509 /* SIGHUP/restart any dnsmasq or radvd daemons.
1510  * This should be called when libvirtd is restarted.
1511  */
1512 static void
1513 networkRefreshDaemons(virNetworkDriverStatePtr driver)
1514 {
1515     size_t i;
1516
1517     VIR_INFO("Refreshing network daemons");
1518
1519     for (i = 0; i < driver->networks.count; i++) {
1520         virNetworkObjPtr network = driver->networks.objs[i];
1521
1522         virNetworkObjLock(network);
1523         if (virNetworkObjIsActive(network) &&
1524             ((network->def->forward.type == VIR_NETWORK_FORWARD_NONE) ||
1525              (network->def->forward.type == VIR_NETWORK_FORWARD_NAT) ||
1526              (network->def->forward.type == VIR_NETWORK_FORWARD_ROUTE))) {
1527             /* Only the three L3 network types that are configured by
1528              * libvirt will have a dnsmasq or radvd daemon associated
1529              * with them.  Here we send a SIGHUP to an existing
1530              * dnsmasq and/or radvd, or restart them if they've
1531              * disappeared.
1532              */
1533             networkRefreshDhcpDaemon(driver, network);
1534             networkRefreshRadvd(driver, network);
1535         }
1536         virNetworkObjUnlock(network);
1537     }
1538 }
1539
1540 static void
1541 networkReloadFirewallRules(virNetworkDriverStatePtr driver)
1542 {
1543     size_t i;
1544
1545     VIR_INFO("Reloading iptables rules");
1546
1547     for (i = 0; i < driver->networks.count; i++) {
1548         virNetworkObjPtr network = driver->networks.objs[i];
1549
1550         virNetworkObjLock(network);
1551         if (virNetworkObjIsActive(network) &&
1552             ((network->def->forward.type == VIR_NETWORK_FORWARD_NONE) ||
1553              (network->def->forward.type == VIR_NETWORK_FORWARD_NAT) ||
1554              (network->def->forward.type == VIR_NETWORK_FORWARD_ROUTE))) {
1555             /* Only the three L3 network types that are configured by libvirt
1556              * need to have iptables rules reloaded.
1557              */
1558             networkRemoveFirewallRules(network);
1559             if (networkAddFirewallRules(network) < 0) {
1560                 /* failed to add but already logged */
1561             }
1562         }
1563         virNetworkObjUnlock(network);
1564     }
1565 }
1566
1567 /* Enable IP Forwarding. Return 0 for success, -1 for failure. */
1568 static int
1569 networkEnableIpForwarding(bool enableIPv4, bool enableIPv6)
1570 {
1571     int ret = 0;
1572 #ifdef HAVE_SYSCTLBYNAME
1573     int enabled = 1;
1574     if (enableIPv4)
1575         ret = sysctlbyname("net.inet.ip.forwarding", NULL, 0,
1576                             &enabled, sizeof(enabled));
1577     if (enableIPv6 && ret == 0)
1578         ret = sysctlbyname("net.inet6.ip6.forwarding", NULL, 0,
1579                             &enabled, sizeof(enabled));
1580 #else
1581     if (enableIPv4)
1582         ret = virFileWriteStr("/proc/sys/net/ipv4/ip_forward", "1\n", 0);
1583     if (enableIPv6 && ret == 0)
1584         ret = virFileWriteStr("/proc/sys/net/ipv6/conf/all/forwarding", "1\n", 0);
1585 #endif
1586     return ret;
1587 }
1588
1589 #define SYSCTL_PATH "/proc/sys"
1590
1591 static int
1592 networkSetIPv6Sysctls(virNetworkObjPtr network)
1593 {
1594     char *field = NULL;
1595     int ret = -1;
1596
1597     if (!virNetworkDefGetIpByIndex(network->def, AF_INET6, 0)) {
1598         /* Only set disable_ipv6 if there are no ipv6 addresses defined for
1599          * the network.
1600          */
1601         if (virAsprintf(&field, SYSCTL_PATH "/net/ipv6/conf/%s/disable_ipv6",
1602                         network->def->bridge) < 0)
1603             goto cleanup;
1604
1605         if (access(field, W_OK) < 0 && errno == ENOENT) {
1606             VIR_DEBUG("ipv6 appears to already be disabled on %s",
1607                       network->def->bridge);
1608             ret = 0;
1609             goto cleanup;
1610         }
1611
1612         if (virFileWriteStr(field, "1", 0) < 0) {
1613             virReportSystemError(errno,
1614                                  _("cannot write to %s to disable IPv6 on bridge %s"),
1615                                  field, network->def->bridge);
1616             goto cleanup;
1617         }
1618         VIR_FREE(field);
1619     }
1620
1621     /* The rest of the ipv6 sysctl tunables should always be set,
1622      * whether or not we're using ipv6 on this bridge.
1623      */
1624
1625     /* Prevent guests from hijacking the host network by sending out
1626      * their own router advertisements.
1627      */
1628     if (virAsprintf(&field, SYSCTL_PATH "/net/ipv6/conf/%s/accept_ra",
1629                     network->def->bridge) < 0)
1630         goto cleanup;
1631
1632     if (virFileWriteStr(field, "0", 0) < 0) {
1633         virReportSystemError(errno,
1634                              _("cannot disable %s"), field);
1635         goto cleanup;
1636     }
1637     VIR_FREE(field);
1638
1639     /* All interfaces used as a gateway (which is what this is, by
1640      * definition), must always have autoconf=0.
1641      */
1642     if (virAsprintf(&field, SYSCTL_PATH "/net/ipv6/conf/%s/autoconf",
1643                     network->def->bridge) < 0)
1644         goto cleanup;
1645
1646     if (virFileWriteStr(field, "0", 0) < 0) {
1647         virReportSystemError(errno,
1648                              _("cannot disable %s"), field);
1649         goto cleanup;
1650     }
1651
1652     ret = 0;
1653 cleanup:
1654     VIR_FREE(field);
1655     return ret;
1656 }
1657
1658 /* add an IP address to a bridge */
1659 static int
1660 networkAddAddrToBridge(virNetworkObjPtr network,
1661                        virNetworkIpDefPtr ipdef)
1662 {
1663     int prefix = virNetworkIpDefPrefix(ipdef);
1664
1665     if (prefix < 0) {
1666         virReportError(VIR_ERR_INTERNAL_ERROR,
1667                        _("bridge '%s' has an invalid netmask or IP address"),
1668                        network->def->bridge);
1669         return -1;
1670     }
1671
1672     if (virNetDevSetIPv4Address(network->def->bridge,
1673                                 &ipdef->address, prefix) < 0)
1674         return -1;
1675
1676     return 0;
1677 }
1678
1679 /* add an IP (static) route to a bridge */
1680 static int
1681 networkAddRouteToBridge(virNetworkObjPtr network,
1682                         virNetworkRouteDefPtr routedef)
1683 {
1684     int prefix = 0;
1685     unsigned int metric;
1686     virSocketAddrPtr addr = &routedef->address;
1687     virSocketAddrPtr mask = &routedef->netmask;
1688     virSocketAddr zero;
1689
1690     /* this creates an all-0 address of the appropriate family */
1691     ignore_value(virSocketAddrParse(&zero,
1692                                     (VIR_SOCKET_ADDR_IS_FAMILY(addr,AF_INET)
1693                                      ? "0.0.0.0" : "::"),
1694                                     VIR_SOCKET_ADDR_FAMILY(addr)));
1695
1696     if (virSocketAddrEqual(addr, &zero)) {
1697         if (routedef->has_prefix && routedef->prefix == 0)
1698             prefix = 0;
1699         else if ((VIR_SOCKET_ADDR_IS_FAMILY(mask, AF_INET) &&
1700                 virSocketAddrEqual(mask, &zero)))
1701             prefix = 0;
1702         else
1703             prefix = virSocketAddrGetIpPrefix(addr, mask, routedef->prefix);
1704     } else {
1705         prefix = virSocketAddrGetIpPrefix(addr, mask, routedef->prefix);
1706     }
1707
1708     if (prefix < 0) {
1709         virReportError(VIR_ERR_INTERNAL_ERROR,
1710                        _("network '%s' has an invalid netmask "
1711                          "or IP address in route definition"),
1712                        network->def->name);
1713         return -1;
1714     }
1715
1716     if (routedef->has_metric && routedef->metric > 0)
1717         metric = routedef->metric;
1718     else
1719         metric = 1;
1720
1721     if (virNetDevAddRoute(network->def->bridge, &routedef->address,
1722                           prefix, &routedef->gateway, metric) < 0) {
1723         return -1;
1724     }
1725     return 0;
1726 }
1727
1728 static int
1729 networkStartNetworkVirtual(virNetworkDriverStatePtr driver,
1730                           virNetworkObjPtr network)
1731 {
1732     size_t i;
1733     bool v4present = false, v6present = false;
1734     virErrorPtr save_err = NULL;
1735     virNetworkIpDefPtr ipdef;
1736     virNetworkRouteDefPtr routedef;
1737     char *macTapIfName = NULL;
1738     int tapfd = -1;
1739
1740     /* Check to see if any network IP collides with an existing route */
1741     if (networkCheckRouteCollision(network) < 0)
1742         return -1;
1743
1744     /* Create and configure the bridge device */
1745     if (virNetDevBridgeCreate(network->def->bridge) < 0)
1746         return -1;
1747
1748     if (network->def->mac_specified) {
1749         /* To set a mac for the bridge, we need to define a dummy tap
1750          * device, set its mac, then attach it to the bridge. As long
1751          * as its mac address is lower than any other interface that
1752          * gets attached, the bridge will always maintain this mac
1753          * address.
1754          */
1755         macTapIfName = networkBridgeDummyNicName(network->def->bridge);
1756         if (!macTapIfName)
1757             goto err0;
1758         /* Keep tun fd open and interface up to allow for IPv6 DAD to happen */
1759         if (virNetDevTapCreateInBridgePort(network->def->bridge,
1760                                            &macTapIfName, &network->def->mac,
1761                                            NULL, &tapfd, 1, NULL, NULL,
1762                                            VIR_NETDEV_TAP_CREATE_USE_MAC_FOR_BRIDGE |
1763                                            VIR_NETDEV_TAP_CREATE_IFUP |
1764                                            VIR_NETDEV_TAP_CREATE_PERSIST) < 0) {
1765             VIR_FREE(macTapIfName);
1766             goto err0;
1767         }
1768     }
1769
1770     /* Set bridge options */
1771
1772     /* delay is configured in seconds, but virNetDevBridgeSetSTPDelay
1773      * expects milliseconds
1774      */
1775     if (virNetDevBridgeSetSTPDelay(network->def->bridge,
1776                                    network->def->delay * 1000) < 0)
1777         goto err1;
1778
1779     if (virNetDevBridgeSetSTP(network->def->bridge,
1780                               network->def->stp ? true : false) < 0)
1781         goto err1;
1782
1783     /* Disable IPv6 on the bridge if there are no IPv6 addresses
1784      * defined, and set other IPv6 sysctl tunables appropriately.
1785      */
1786     if (networkSetIPv6Sysctls(network) < 0)
1787         goto err1;
1788
1789     /* Add "once per network" rules */
1790     if (networkAddFirewallRules(network) < 0)
1791         goto err1;
1792
1793     for (i = 0;
1794          (ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, i));
1795          i++) {
1796         if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET))
1797             v4present = true;
1798         if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6))
1799             v6present = true;
1800
1801         /* Add the IP address/netmask to the bridge */
1802         if (networkAddAddrToBridge(network, ipdef) < 0) {
1803             goto err2;
1804         }
1805     }
1806
1807     /* Bring up the bridge interface */
1808     if (virNetDevSetOnline(network->def->bridge, 1) < 0)
1809         goto err2;
1810
1811     for (i = 0; i < network->def->nroutes; i++) {
1812         routedef = &network->def->routes[i];
1813         /* Add the IP route to the bridge */
1814         /* ignore errors, error msg will be generated */
1815         /* but libvirt will not know and net-destroy will work. */
1816         if (VIR_SOCKET_ADDR_VALID(&routedef->gateway)) {
1817             if (networkAddRouteToBridge(network, routedef) < 0) {
1818                 /* an error occurred adding the static route */
1819                 continue; /* for now, do nothing */
1820             }
1821         }
1822     }
1823
1824     /* If forward.type != NONE, turn on global IP forwarding */
1825     if (network->def->forward.type != VIR_NETWORK_FORWARD_NONE &&
1826         networkEnableIpForwarding(v4present, v6present) < 0) {
1827         virReportSystemError(errno, "%s",
1828                              _("failed to enable IP forwarding"));
1829         goto err3;
1830     }
1831
1832
1833     /* start dnsmasq if there are any IP addresses (v4 or v6) */
1834     if ((v4present || v6present) &&
1835         networkStartDhcpDaemon(driver, network) < 0)
1836         goto err3;
1837
1838     /* start radvd if there are any ipv6 addresses */
1839     if (v6present && networkStartRadvd(driver, network) < 0)
1840         goto err4;
1841
1842     /* DAD has happened (dnsmasq waits for it), dnsmasq is now bound to the
1843      * bridge's IPv6 address, so we can now set the dummy tun down.
1844      */
1845     if (tapfd >= 0) {
1846         if (virNetDevSetOnline(macTapIfName, false) < 0)
1847             goto err4;
1848         VIR_FORCE_CLOSE(tapfd);
1849     }
1850
1851     if (virNetDevBandwidthSet(network->def->bridge,
1852                               network->def->bandwidth, true) < 0) {
1853         virReportError(VIR_ERR_INTERNAL_ERROR,
1854                        _("cannot set bandwidth limits on %s"),
1855                        network->def->bridge);
1856         goto err5;
1857     }
1858
1859     VIR_FREE(macTapIfName);
1860
1861     return 0;
1862
1863  err5:
1864     virNetDevBandwidthClear(network->def->bridge);
1865
1866  err4:
1867     if (!save_err)
1868         save_err = virSaveLastError();
1869
1870     if (network->dnsmasqPid > 0) {
1871         kill(network->dnsmasqPid, SIGTERM);
1872         network->dnsmasqPid = -1;
1873     }
1874
1875  err3:
1876     if (!save_err)
1877         save_err = virSaveLastError();
1878     ignore_value(virNetDevSetOnline(network->def->bridge, 0));
1879
1880  err2:
1881     if (!save_err)
1882         save_err = virSaveLastError();
1883     networkRemoveFirewallRules(network);
1884
1885  err1:
1886     if (!save_err)
1887         save_err = virSaveLastError();
1888
1889     if (macTapIfName) {
1890         VIR_FORCE_CLOSE(tapfd);
1891         ignore_value(virNetDevTapDelete(macTapIfName));
1892         VIR_FREE(macTapIfName);
1893     }
1894
1895  err0:
1896     if (!save_err)
1897         save_err = virSaveLastError();
1898     ignore_value(virNetDevBridgeDelete(network->def->bridge));
1899
1900     if (save_err) {
1901         virSetError(save_err);
1902         virFreeError(save_err);
1903     }
1904     /* coverity[leaked_handle] - 'tapfd' is not leaked */
1905     return -1;
1906 }
1907
1908 static int networkShutdownNetworkVirtual(virNetworkDriverStatePtr driver ATTRIBUTE_UNUSED,
1909                                          virNetworkObjPtr network)
1910 {
1911     virNetDevBandwidthClear(network->def->bridge);
1912
1913     if (network->radvdPid > 0) {
1914         char *radvdpidbase;
1915
1916         kill(network->radvdPid, SIGTERM);
1917         /* attempt to delete the pidfile we created */
1918         if ((radvdpidbase = networkRadvdPidfileBasename(network->def->name))) {
1919             virPidFileDelete(driverState->pidDir, radvdpidbase);
1920             VIR_FREE(radvdpidbase);
1921         }
1922     }
1923
1924     if (network->dnsmasqPid > 0)
1925         kill(network->dnsmasqPid, SIGTERM);
1926
1927     if (network->def->mac_specified) {
1928         char *macTapIfName = networkBridgeDummyNicName(network->def->bridge);
1929         if (macTapIfName) {
1930             ignore_value(virNetDevTapDelete(macTapIfName));
1931             VIR_FREE(macTapIfName);
1932         }
1933     }
1934
1935     ignore_value(virNetDevSetOnline(network->def->bridge, 0));
1936
1937     networkRemoveFirewallRules(network);
1938
1939     ignore_value(virNetDevBridgeDelete(network->def->bridge));
1940
1941     /* See if its still alive and really really kill it */
1942     if (network->dnsmasqPid > 0 &&
1943         (kill(network->dnsmasqPid, 0) == 0))
1944         kill(network->dnsmasqPid, SIGKILL);
1945     network->dnsmasqPid = -1;
1946
1947     if (network->radvdPid > 0 &&
1948         (kill(network->radvdPid, 0) == 0))
1949         kill(network->radvdPid, SIGKILL);
1950     network->radvdPid = -1;
1951
1952     return 0;
1953 }
1954
1955 static int
1956 networkStartNetworkExternal(virNetworkDriverStatePtr driver ATTRIBUTE_UNUSED,
1957                             virNetworkObjPtr network ATTRIBUTE_UNUSED)
1958 {
1959     /* put anything here that needs to be done each time a network of
1960      * type BRIDGE, PRIVATE, VEPA, HOSTDEV or PASSTHROUGH is started. On
1961      * failure, undo anything you've done, and return -1. On success
1962      * return 0.
1963      */
1964     return 0;
1965 }
1966
1967 static int networkShutdownNetworkExternal(virNetworkDriverStatePtr driver ATTRIBUTE_UNUSED,
1968                                         virNetworkObjPtr network ATTRIBUTE_UNUSED)
1969 {
1970     /* put anything here that needs to be done each time a network of
1971      * type BRIDGE, PRIVATE, VEPA, HOSTDEV or PASSTHROUGH is shutdown. On
1972      * failure, undo anything you've done, and return -1. On success
1973      * return 0.
1974      */
1975     return 0;
1976 }
1977
1978 static int
1979 networkStartNetwork(virNetworkDriverStatePtr driver,
1980                     virNetworkObjPtr network)
1981 {
1982     int ret = 0;
1983
1984     if (virNetworkObjIsActive(network)) {
1985         virReportError(VIR_ERR_OPERATION_INVALID,
1986                        "%s", _("network is already active"));
1987         return -1;
1988     }
1989
1990     if (virNetworkObjSetDefTransient(network, true) < 0)
1991         return -1;
1992
1993     switch (network->def->forward.type) {
1994
1995     case VIR_NETWORK_FORWARD_NONE:
1996     case VIR_NETWORK_FORWARD_NAT:
1997     case VIR_NETWORK_FORWARD_ROUTE:
1998         ret = networkStartNetworkVirtual(driver, network);
1999         break;
2000
2001     case VIR_NETWORK_FORWARD_BRIDGE:
2002     case VIR_NETWORK_FORWARD_PRIVATE:
2003     case VIR_NETWORK_FORWARD_VEPA:
2004     case VIR_NETWORK_FORWARD_PASSTHROUGH:
2005     case VIR_NETWORK_FORWARD_HOSTDEV:
2006         ret = networkStartNetworkExternal(driver, network);
2007         break;
2008     }
2009
2010     if (ret < 0) {
2011         virNetworkObjUnsetDefTransient(network);
2012         return ret;
2013     }
2014
2015     /* Persist the live configuration now that anything autogenerated
2016      * is setup.
2017      */
2018     if ((ret = virNetworkSaveStatus(driverState->stateDir,
2019                                     network)) < 0) {
2020         goto error;
2021     }
2022
2023     VIR_INFO("Starting up network '%s'", network->def->name);
2024     network->active = 1;
2025
2026 error:
2027     if (ret < 0) {
2028         virErrorPtr save_err = virSaveLastError();
2029         int save_errno = errno;
2030         networkShutdownNetwork(driver, network);
2031         virSetError(save_err);
2032         virFreeError(save_err);
2033         errno = save_errno;
2034     }
2035     return ret;
2036 }
2037
2038 static int networkShutdownNetwork(virNetworkDriverStatePtr driver,
2039                                         virNetworkObjPtr network)
2040 {
2041     int ret = 0;
2042     char *stateFile;
2043
2044     VIR_INFO("Shutting down network '%s'", network->def->name);
2045
2046     if (!virNetworkObjIsActive(network))
2047         return 0;
2048
2049     stateFile = virNetworkConfigFile(driverState->stateDir,
2050                                      network->def->name);
2051     if (!stateFile)
2052         return -1;
2053
2054     unlink(stateFile);
2055     VIR_FREE(stateFile);
2056
2057     switch (network->def->forward.type) {
2058
2059     case VIR_NETWORK_FORWARD_NONE:
2060     case VIR_NETWORK_FORWARD_NAT:
2061     case VIR_NETWORK_FORWARD_ROUTE:
2062         ret = networkShutdownNetworkVirtual(driver, network);
2063         break;
2064
2065     case VIR_NETWORK_FORWARD_BRIDGE:
2066     case VIR_NETWORK_FORWARD_PRIVATE:
2067     case VIR_NETWORK_FORWARD_VEPA:
2068     case VIR_NETWORK_FORWARD_PASSTHROUGH:
2069     case VIR_NETWORK_FORWARD_HOSTDEV:
2070         ret = networkShutdownNetworkExternal(driver, network);
2071         break;
2072     }
2073
2074     network->active = 0;
2075     virNetworkObjUnsetDefTransient(network);
2076     return ret;
2077 }
2078
2079
2080 static virNetworkPtr networkLookupByUUID(virConnectPtr conn,
2081                                          const unsigned char *uuid) {
2082     virNetworkDriverStatePtr driver = conn->networkPrivateData;
2083     virNetworkObjPtr network;
2084     virNetworkPtr ret = NULL;
2085
2086     networkDriverLock(driver);
2087     network = virNetworkFindByUUID(&driver->networks, uuid);
2088     networkDriverUnlock(driver);
2089     if (!network) {
2090         virReportError(VIR_ERR_NO_NETWORK,
2091                        "%s", _("no network with matching uuid"));
2092         goto cleanup;
2093     }
2094
2095     if (virNetworkLookupByUUIDEnsureACL(conn, network->def) < 0)
2096         goto cleanup;
2097
2098     ret = virGetNetwork(conn, network->def->name, network->def->uuid);
2099
2100 cleanup:
2101     if (network)
2102         virNetworkObjUnlock(network);
2103     return ret;
2104 }
2105
2106 static virNetworkPtr networkLookupByName(virConnectPtr conn,
2107                                          const char *name) {
2108     virNetworkDriverStatePtr driver = conn->networkPrivateData;
2109     virNetworkObjPtr network;
2110     virNetworkPtr ret = NULL;
2111
2112     networkDriverLock(driver);
2113     network = virNetworkFindByName(&driver->networks, name);
2114     networkDriverUnlock(driver);
2115     if (!network) {
2116         virReportError(VIR_ERR_NO_NETWORK,
2117                        _("no network with matching name '%s'"), name);
2118         goto cleanup;
2119     }
2120
2121     if (virNetworkLookupByNameEnsureACL(conn, network->def) < 0)
2122         goto cleanup;
2123
2124     ret = virGetNetwork(conn, network->def->name, network->def->uuid);
2125
2126 cleanup:
2127     if (network)
2128         virNetworkObjUnlock(network);
2129     return ret;
2130 }
2131
2132 static virDrvOpenStatus networkOpen(virConnectPtr conn,
2133                                     virConnectAuthPtr auth ATTRIBUTE_UNUSED,
2134                                     unsigned int flags)
2135 {
2136     virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);
2137
2138     if (!driverState)
2139         return VIR_DRV_OPEN_DECLINED;
2140
2141     conn->networkPrivateData = driverState;
2142     return VIR_DRV_OPEN_SUCCESS;
2143 }
2144
2145 static int networkClose(virConnectPtr conn) {
2146     conn->networkPrivateData = NULL;
2147     return 0;
2148 }
2149
2150 static int networkConnectNumOfNetworks(virConnectPtr conn) {
2151     int nactive = 0;
2152     size_t i;
2153     virNetworkDriverStatePtr driver = conn->networkPrivateData;
2154
2155     if (virConnectNumOfNetworksEnsureACL(conn) < 0)
2156         return -1;
2157
2158     networkDriverLock(driver);
2159     for (i = 0; i < driver->networks.count; i++) {
2160         virNetworkObjPtr obj = driver->networks.objs[i];
2161         virNetworkObjLock(obj);
2162         if (virConnectNumOfNetworksCheckACL(conn, obj->def) &&
2163             virNetworkObjIsActive(obj))
2164             nactive++;
2165         virNetworkObjUnlock(obj);
2166     }
2167     networkDriverUnlock(driver);
2168
2169     return nactive;
2170 }
2171
2172 static int networkConnectListNetworks(virConnectPtr conn, char **const names, int nnames) {
2173     virNetworkDriverStatePtr driver = conn->networkPrivateData;
2174     int got = 0;
2175     size_t i;
2176
2177     if (virConnectListNetworksEnsureACL(conn) < 0)
2178         return -1;
2179
2180     networkDriverLock(driver);
2181     for (i = 0; i < driver->networks.count && got < nnames; i++) {
2182         virNetworkObjPtr obj = driver->networks.objs[i];
2183         virNetworkObjLock(obj);
2184         if (virConnectListNetworksCheckACL(conn, obj->def) &&
2185             virNetworkObjIsActive(obj)) {
2186             if (VIR_STRDUP(names[got], obj->def->name) < 0) {
2187                 virNetworkObjUnlock(obj);
2188                 goto cleanup;
2189             }
2190             got++;
2191         }
2192         virNetworkObjUnlock(obj);
2193     }
2194     networkDriverUnlock(driver);
2195
2196     return got;
2197
2198  cleanup:
2199     networkDriverUnlock(driver);
2200     for (i = 0; i < got; i++)
2201         VIR_FREE(names[i]);
2202     return -1;
2203 }
2204
2205 static int networkConnectNumOfDefinedNetworks(virConnectPtr conn) {
2206     int ninactive = 0;
2207     size_t i;
2208     virNetworkDriverStatePtr driver = conn->networkPrivateData;
2209
2210     if (virConnectNumOfDefinedNetworksEnsureACL(conn) < 0)
2211         return -1;
2212
2213     networkDriverLock(driver);
2214     for (i = 0; i < driver->networks.count; i++) {
2215         virNetworkObjPtr obj = driver->networks.objs[i];
2216         virNetworkObjLock(obj);
2217         if (virConnectNumOfDefinedNetworksCheckACL(conn, obj->def) &&
2218             !virNetworkObjIsActive(obj))
2219             ninactive++;
2220         virNetworkObjUnlock(obj);
2221     }
2222     networkDriverUnlock(driver);
2223
2224     return ninactive;
2225 }
2226
2227 static int networkConnectListDefinedNetworks(virConnectPtr conn, char **const names, int nnames) {
2228     virNetworkDriverStatePtr driver = conn->networkPrivateData;
2229     int got = 0;
2230     size_t i;
2231
2232     if (virConnectListDefinedNetworksEnsureACL(conn) < 0)
2233         return -1;
2234
2235     networkDriverLock(driver);
2236     for (i = 0; i < driver->networks.count && got < nnames; i++) {
2237         virNetworkObjPtr obj = driver->networks.objs[i];
2238         virNetworkObjLock(obj);
2239         if (virConnectListDefinedNetworksCheckACL(conn, obj->def) &&
2240             !virNetworkObjIsActive(obj)) {
2241             if (VIR_STRDUP(names[got], obj->def->name) < 0) {
2242                 virNetworkObjUnlock(obj);
2243                 goto cleanup;
2244             }
2245             got++;
2246         }
2247         virNetworkObjUnlock(obj);
2248     }
2249     networkDriverUnlock(driver);
2250     return got;
2251
2252  cleanup:
2253     networkDriverUnlock(driver);
2254     for (i = 0; i < got; i++)
2255         VIR_FREE(names[i]);
2256     return -1;
2257 }
2258
2259 static int
2260 networkConnectListAllNetworks(virConnectPtr conn,
2261                               virNetworkPtr **nets,
2262                               unsigned int flags)
2263 {
2264     virNetworkDriverStatePtr driver = conn->networkPrivateData;
2265     int ret = -1;
2266
2267     virCheckFlags(VIR_CONNECT_LIST_NETWORKS_FILTERS_ALL, -1);
2268
2269     if (virConnectListAllNetworksEnsureACL(conn) < 0)
2270         goto cleanup;
2271
2272     networkDriverLock(driver);
2273     ret = virNetworkObjListExport(conn, driver->networks, nets,
2274                                   virConnectListAllNetworksCheckACL,
2275                                   flags);
2276     networkDriverUnlock(driver);
2277
2278 cleanup:
2279     return ret;
2280 }
2281
2282 static int networkIsActive(virNetworkPtr net)
2283 {
2284     virNetworkObjPtr obj;
2285     int ret = -1;
2286
2287     if (!(obj = networkObjFromNetwork(net)))
2288         return ret;
2289
2290     if (virNetworkIsActiveEnsureACL(net->conn, obj->def) < 0)
2291         goto cleanup;
2292
2293     ret = virNetworkObjIsActive(obj);
2294
2295 cleanup:
2296     if (obj)
2297         virNetworkObjUnlock(obj);
2298     return ret;
2299 }
2300
2301 static int networkIsPersistent(virNetworkPtr net)
2302 {
2303     virNetworkObjPtr obj;
2304     int ret = -1;
2305
2306     if (!(obj = networkObjFromNetwork(net)))
2307         return ret;
2308
2309     if (virNetworkIsPersistentEnsureACL(net->conn, obj->def) < 0)
2310         goto cleanup;
2311
2312     ret = obj->persistent;
2313
2314 cleanup:
2315     if (obj)
2316         virNetworkObjUnlock(obj);
2317     return ret;
2318 }
2319
2320
2321 static int
2322 networkValidate(virNetworkDriverStatePtr driver,
2323                 virNetworkDefPtr def,
2324                 bool check_active)
2325 {
2326     size_t i;
2327     bool vlanUsed, vlanAllowed, badVlanUse = false;
2328     virPortGroupDefPtr defaultPortGroup = NULL;
2329     virNetworkIpDefPtr ipdef;
2330     bool ipv4def = false, ipv6def = false;
2331
2332     /* check for duplicate networks */
2333     if (virNetworkObjIsDuplicate(&driver->networks, def, check_active) < 0)
2334         return -1;
2335
2336     /* Only the three L3 network types that are configured by libvirt
2337      * need to have a bridge device name / mac address provided
2338      */
2339     if (def->forward.type == VIR_NETWORK_FORWARD_NONE ||
2340         def->forward.type == VIR_NETWORK_FORWARD_NAT ||
2341         def->forward.type == VIR_NETWORK_FORWARD_ROUTE) {
2342
2343         if (virNetworkSetBridgeName(&driver->networks, def, 1))
2344             return -1;
2345
2346         virNetworkSetBridgeMacAddr(def);
2347     } else {
2348         /* They are also the only types that currently support setting
2349          * an IP address for the host-side device (bridge)
2350          */
2351         if (virNetworkDefGetIpByIndex(def, AF_UNSPEC, 0)) {
2352             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
2353                            _("Unsupported <ip> element in network %s "
2354                              "with forward mode='%s'"),
2355                            def->name,
2356                            virNetworkForwardTypeToString(def->forward.type));
2357             return -1;
2358         }
2359         if (def->dns.ntxts || def->dns.nhosts || def->dns.nsrvs) {
2360             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
2361                            _("Unsupported <dns> element in network %s "
2362                              "with forward mode='%s'"),
2363                            def->name,
2364                            virNetworkForwardTypeToString(def->forward.type));
2365             return -1;
2366         }
2367         if (def->domain) {
2368             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
2369                            _("Unsupported <domain> element in network %s "
2370                              "with forward mode='%s'"),
2371                            def->name,
2372                            virNetworkForwardTypeToString(def->forward.type));
2373             return -1;
2374         }
2375     }
2376
2377     /* We only support dhcp on one IPv4 address and
2378      * on one IPv6 address per defined network
2379      */
2380     for (i = 0;
2381          (ipdef = virNetworkDefGetIpByIndex(def, AF_UNSPEC, i));
2382          i++) {
2383         if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET)) {
2384             if (ipdef->nranges || ipdef->nhosts) {
2385                 if (ipv4def) {
2386                     virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
2387                                _("Multiple IPv4 dhcp sections found -- "
2388                                  "dhcp is supported only for a "
2389                                  "single IPv4 address on each network"));
2390                     return -1;
2391                 } else {
2392                     ipv4def = true;
2393                 }
2394             }
2395         }
2396         if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6)) {
2397             if (ipdef->nranges || ipdef->nhosts) {
2398                 if (ipv6def) {
2399                     virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
2400                                _("Multiple IPv6 dhcp sections found -- "
2401                                  "dhcp is supported only for a "
2402                                  "single IPv6 address on each network"));
2403                     return -1;
2404                 } else {
2405                     ipv6def = true;
2406                 }
2407             }
2408         }
2409     }
2410
2411     /* The only type of networks that currently support transparent
2412      * vlan configuration are those using hostdev sr-iov devices from
2413      * a pool, and those using an Open vSwitch bridge.
2414      */
2415
2416     vlanAllowed = ((def->forward.type == VIR_NETWORK_FORWARD_BRIDGE &&
2417                    def->virtPortProfile &&
2418                    def->virtPortProfile->virtPortType
2419                     == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH) ||
2420                    def->forward.type == VIR_NETWORK_FORWARD_HOSTDEV);
2421
2422     vlanUsed = def->vlan.nTags > 0;
2423     for (i = 0; i < def->nPortGroups; i++) {
2424         if (vlanUsed || def->portGroups[i].vlan.nTags > 0) {
2425             /* anyone using this portgroup will get a vlan tag. Verify
2426              * that they will also be using an openvswitch connection,
2427              * as that is the only type of network that currently
2428              * supports a vlan tag.
2429              */
2430             if (def->portGroups[i].virtPortProfile) {
2431                 if (def->forward.type != VIR_NETWORK_FORWARD_BRIDGE ||
2432                     def->portGroups[i].virtPortProfile->virtPortType
2433                     != VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH) {
2434                     badVlanUse = true;
2435                 }
2436             } else if (!vlanAllowed) {
2437                 /* virtualport taken from base network definition */
2438                 badVlanUse = true;
2439             }
2440         }
2441         if (def->portGroups[i].isDefault) {
2442             if (defaultPortGroup) {
2443                 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
2444                                _("network '%s' has multiple default "
2445                                  "<portgroup> elements (%s and %s), "
2446                                  "but only one default is allowed"),
2447                                def->name, defaultPortGroup->name,
2448                                def->portGroups[i].name);
2449                 return -1;
2450             }
2451             defaultPortGroup = &def->portGroups[i];
2452         }
2453     }
2454     if (badVlanUse ||
2455         (vlanUsed && !vlanAllowed && !defaultPortGroup)) {
2456         /* NB: if defaultPortGroup is set, we don't directly look at
2457          * vlanUsed && !vlanAllowed, because the network will never be
2458          * used without having a portgroup added in, so all necessary
2459          * checks were done in the loop above.
2460          */
2461         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
2462                        _("<vlan> element specified for network %s, "
2463                          "whose type doesn't support vlan configuration"),
2464                        def->name);
2465         return -1;
2466     }
2467     return 0;
2468 }
2469
2470 static virNetworkPtr networkCreateXML(virConnectPtr conn, const char *xml) {
2471     virNetworkDriverStatePtr driver = conn->networkPrivateData;
2472     virNetworkDefPtr def;
2473     virNetworkObjPtr network = NULL;
2474     virNetworkPtr ret = NULL;
2475
2476     networkDriverLock(driver);
2477
2478     if (!(def = virNetworkDefParseString(xml)))
2479         goto cleanup;
2480
2481     if (virNetworkCreateXMLEnsureACL(conn, def) < 0)
2482         goto cleanup;
2483
2484     if (networkValidate(driver, def, true) < 0)
2485        goto cleanup;
2486
2487     /* NB: "live" is false because this transient network hasn't yet
2488      * been started
2489      */
2490     if (!(network = virNetworkAssignDef(&driver->networks, def, false)))
2491         goto cleanup;
2492     def = NULL;
2493
2494     if (networkStartNetwork(driver, network) < 0) {
2495         virNetworkRemoveInactive(&driver->networks,
2496                                  network);
2497         network = NULL;
2498         goto cleanup;
2499     }
2500
2501     VIR_INFO("Creating network '%s'", network->def->name);
2502     ret = virGetNetwork(conn, network->def->name, network->def->uuid);
2503
2504 cleanup:
2505     virNetworkDefFree(def);
2506     if (network)
2507         virNetworkObjUnlock(network);
2508     networkDriverUnlock(driver);
2509     return ret;
2510 }
2511
2512 static virNetworkPtr networkDefineXML(virConnectPtr conn, const char *xml) {
2513     virNetworkDriverStatePtr driver = conn->networkPrivateData;
2514     virNetworkDefPtr def = NULL;
2515     bool freeDef = true;
2516     virNetworkObjPtr network = NULL;
2517     virNetworkPtr ret = NULL;
2518
2519     networkDriverLock(driver);
2520
2521     if (!(def = virNetworkDefParseString(xml)))
2522         goto cleanup;
2523
2524     if (virNetworkDefineXMLEnsureACL(conn, def) < 0)
2525         goto cleanup;
2526
2527     if (networkValidate(driver, def, false) < 0)
2528        goto cleanup;
2529
2530     if ((network = virNetworkFindByName(&driver->networks, def->name))) {
2531         network->persistent = 1;
2532         if (virNetworkObjAssignDef(network, def, false) < 0)
2533             goto cleanup;
2534     } else {
2535         if (!(network = virNetworkAssignDef(&driver->networks, def, false)))
2536             goto cleanup;
2537     }
2538
2539     /* define makes the network persistent - always */
2540     network->persistent = 1;
2541
2542     /* def was asigned */
2543     freeDef = false;
2544
2545     if (virNetworkSaveConfig(driver->networkConfigDir, def) < 0) {
2546         if (!virNetworkObjIsActive(network)) {
2547             virNetworkRemoveInactive(&driver->networks, network);
2548             network = NULL;
2549             goto cleanup;
2550         }
2551         network->persistent = 0;
2552         virNetworkDefFree(network->newDef);
2553         network->newDef = NULL;
2554         goto cleanup;
2555     }
2556
2557     VIR_INFO("Defining network '%s'", def->name);
2558     ret = virGetNetwork(conn, def->name, def->uuid);
2559
2560 cleanup:
2561     if (freeDef)
2562        virNetworkDefFree(def);
2563     if (network)
2564         virNetworkObjUnlock(network);
2565     networkDriverUnlock(driver);
2566     return ret;
2567 }
2568
2569 static int
2570 networkUndefine(virNetworkPtr net) {
2571     virNetworkDriverStatePtr driver = net->conn->networkPrivateData;
2572     virNetworkObjPtr network;
2573     int ret = -1;
2574     bool active = false;
2575
2576     networkDriverLock(driver);
2577
2578     network = virNetworkFindByUUID(&driver->networks, net->uuid);
2579     if (!network) {
2580         virReportError(VIR_ERR_NO_NETWORK,
2581                        "%s", _("no network with matching uuid"));
2582         goto cleanup;
2583     }
2584
2585     if (virNetworkUndefineEnsureACL(net->conn, network->def) < 0)
2586         goto cleanup;
2587
2588     if (virNetworkObjIsActive(network))
2589         active = true;
2590
2591     if (virNetworkDeleteConfig(driver->networkConfigDir,
2592                                driver->networkAutostartDir,
2593                                network) < 0)
2594         goto cleanup;
2595
2596     /* make the network transient */
2597     network->persistent = 0;
2598     network->autostart = 0;
2599     virNetworkDefFree(network->newDef);
2600     network->newDef = NULL;
2601
2602     VIR_INFO("Undefining network '%s'", network->def->name);
2603     if (!active) {
2604         if (networkRemoveInactive(driver, network) < 0) {
2605             network = NULL;
2606             goto cleanup;
2607         }
2608         network = NULL;
2609     }
2610
2611     ret = 0;
2612
2613 cleanup:
2614     if (network)
2615         virNetworkObjUnlock(network);
2616     networkDriverUnlock(driver);
2617     return ret;
2618 }
2619
2620 static int
2621 networkUpdate(virNetworkPtr net,
2622               unsigned int command,
2623               unsigned int section,
2624               int parentIndex,
2625               const char *xml,
2626               unsigned int flags)
2627 {
2628     virNetworkDriverStatePtr driver = net->conn->networkPrivateData;
2629     virNetworkObjPtr network = NULL;
2630     int isActive, ret = -1;
2631     size_t i;
2632     virNetworkIpDefPtr ipdef;
2633     bool oldDhcpActive = false;
2634
2635
2636     virCheckFlags(VIR_NETWORK_UPDATE_AFFECT_LIVE |
2637                   VIR_NETWORK_UPDATE_AFFECT_CONFIG,
2638                   -1);
2639
2640     networkDriverLock(driver);
2641
2642     network = virNetworkFindByUUID(&driver->networks, net->uuid);
2643     if (!network) {
2644         virReportError(VIR_ERR_NO_NETWORK,
2645                        "%s", _("no network with matching uuid"));
2646         goto cleanup;
2647     }
2648
2649     if (virNetworkUpdateEnsureACL(net->conn, network->def, flags) < 0)
2650         goto cleanup;
2651
2652     /* see if we are listening for dhcp pre-modification */
2653     for (i = 0;
2654          (ipdef = virNetworkDefGetIpByIndex(network->def, AF_INET, i));
2655          i++) {
2656         if (ipdef->nranges || ipdef->nhosts) {
2657             oldDhcpActive = true;
2658             break;
2659         }
2660     }
2661
2662     /* VIR_NETWORK_UPDATE_AFFECT_CURRENT means "change LIVE if network
2663      * is active, else change CONFIG
2664     */
2665     isActive = virNetworkObjIsActive(network);
2666     if ((flags & (VIR_NETWORK_UPDATE_AFFECT_LIVE |
2667                   VIR_NETWORK_UPDATE_AFFECT_CONFIG)) ==
2668         VIR_NETWORK_UPDATE_AFFECT_CURRENT) {
2669         if (isActive)
2670             flags |= VIR_NETWORK_UPDATE_AFFECT_LIVE;
2671         else
2672             flags |= VIR_NETWORK_UPDATE_AFFECT_CONFIG;
2673     }
2674
2675     /* update the network config in memory/on disk */
2676     if (virNetworkObjUpdate(network, command, section, parentIndex, xml, flags) < 0)
2677         goto cleanup;
2678
2679     if (flags & VIR_NETWORK_UPDATE_AFFECT_CONFIG) {
2680         /* save updated persistent config to disk */
2681         if (virNetworkSaveConfig(driver->networkConfigDir,
2682                                  virNetworkObjGetPersistentDef(network)) < 0) {
2683             goto cleanup;
2684         }
2685     }
2686
2687     if (isActive && (flags & VIR_NETWORK_UPDATE_AFFECT_LIVE)) {
2688         /* rewrite dnsmasq host files, restart dnsmasq, update iptables
2689          * rules, etc, according to which section was modified. Note that
2690          * some sections require multiple actions, so a single switch
2691          * statement is inadequate.
2692          */
2693         if (section == VIR_NETWORK_SECTION_BRIDGE ||
2694             section == VIR_NETWORK_SECTION_DOMAIN ||
2695             section == VIR_NETWORK_SECTION_IP ||
2696             section == VIR_NETWORK_SECTION_IP_DHCP_RANGE) {
2697             /* these sections all change things on the dnsmasq commandline,
2698              * so we need to kill and restart dnsmasq.
2699              */
2700             if (networkRestartDhcpDaemon(driver, network) < 0)
2701                 goto cleanup;
2702
2703         } else if (section == VIR_NETWORK_SECTION_IP_DHCP_HOST) {
2704             /* if we previously weren't listening for dhcp and now we
2705              * are (or vice-versa) then we need to do a restart,
2706              * otherwise we just need to do a refresh (redo the config
2707              * files and send SIGHUP)
2708              */
2709             bool newDhcpActive = false;
2710
2711             for (i = 0;
2712                  (ipdef = virNetworkDefGetIpByIndex(network->def, AF_INET, i));
2713                  i++) {
2714                 if (ipdef->nranges || ipdef->nhosts) {
2715                     newDhcpActive = true;
2716                     break;
2717                 }
2718             }
2719
2720             if ((newDhcpActive != oldDhcpActive &&
2721                  networkRestartDhcpDaemon(driver, network) < 0) ||
2722                 networkRefreshDhcpDaemon(driver, network) < 0) {
2723                 goto cleanup;
2724             }
2725
2726         } else if (section == VIR_NETWORK_SECTION_DNS_HOST ||
2727                    section == VIR_NETWORK_SECTION_DNS_TXT ||
2728                    section == VIR_NETWORK_SECTION_DNS_SRV) {
2729             /* these sections only change things in config files, so we
2730              * can just update the config files and send SIGHUP to
2731              * dnsmasq.
2732              */
2733             if (networkRefreshDhcpDaemon(driver, network) < 0)
2734                 goto cleanup;
2735
2736         }
2737
2738         if (section == VIR_NETWORK_SECTION_IP) {
2739             /* only a change in IP addresses will affect radvd, and all of radvd's
2740              * config is stored in the conf file which will be re-read with a SIGHUP.
2741              */
2742             if (networkRefreshRadvd(driver, network) < 0)
2743                 goto cleanup;
2744         }
2745
2746         if ((section == VIR_NETWORK_SECTION_IP ||
2747              section == VIR_NETWORK_SECTION_FORWARD ||
2748              section == VIR_NETWORK_SECTION_FORWARD_INTERFACE) &&
2749            (network->def->forward.type == VIR_NETWORK_FORWARD_NONE ||
2750             network->def->forward.type == VIR_NETWORK_FORWARD_NAT ||
2751             network->def->forward.type == VIR_NETWORK_FORWARD_ROUTE)) {
2752             /* these could affect the iptables rules */
2753             networkRemoveFirewallRules(network);
2754             if (networkAddFirewallRules(network) < 0)
2755                 goto cleanup;
2756
2757         }
2758
2759         /* save current network state to disk */
2760         if ((ret = virNetworkSaveStatus(driverState->stateDir,
2761                                         network)) < 0) {
2762             goto cleanup;
2763         }
2764     }
2765     ret = 0;
2766 cleanup:
2767     if (network)
2768         virNetworkObjUnlock(network);
2769     networkDriverUnlock(driver);
2770     return ret;
2771 }
2772
2773 static int networkCreate(virNetworkPtr net) {
2774     virNetworkDriverStatePtr driver = net->conn->networkPrivateData;
2775     virNetworkObjPtr network;
2776     int ret = -1;
2777
2778     networkDriverLock(driver);
2779     network = virNetworkFindByUUID(&driver->networks, net->uuid);
2780
2781     if (!network) {
2782         virReportError(VIR_ERR_NO_NETWORK,
2783                        "%s", _("no network with matching uuid"));
2784         goto cleanup;
2785     }
2786
2787     if (virNetworkCreateEnsureACL(net->conn, network->def) < 0)
2788         goto cleanup;
2789
2790     ret = networkStartNetwork(driver, network);
2791
2792 cleanup:
2793     if (network)
2794         virNetworkObjUnlock(network);
2795     networkDriverUnlock(driver);
2796     return ret;
2797 }
2798
2799 static int networkDestroy(virNetworkPtr net) {
2800     virNetworkDriverStatePtr driver = net->conn->networkPrivateData;
2801     virNetworkObjPtr network;
2802     int ret = -1;
2803
2804     networkDriverLock(driver);
2805     network = virNetworkFindByUUID(&driver->networks, net->uuid);
2806
2807     if (!network) {
2808         virReportError(VIR_ERR_NO_NETWORK,
2809                        "%s", _("no network with matching uuid"));
2810         goto cleanup;
2811     }
2812
2813     if (virNetworkDestroyEnsureACL(net->conn, network->def) < 0)
2814         goto cleanup;
2815
2816     if (!virNetworkObjIsActive(network)) {
2817         virReportError(VIR_ERR_OPERATION_INVALID,
2818                        "%s", _("network is not active"));
2819         goto cleanup;
2820     }
2821
2822     if ((ret = networkShutdownNetwork(driver, network)) < 0)
2823         goto cleanup;
2824
2825     if (!network->persistent) {
2826         if (networkRemoveInactive(driver, network) < 0) {
2827             network = NULL;
2828             ret = -1;
2829             goto cleanup;
2830         }
2831         network = NULL;
2832     }
2833
2834 cleanup:
2835     if (network)
2836         virNetworkObjUnlock(network);
2837     networkDriverUnlock(driver);
2838     return ret;
2839 }
2840
2841 static char *networkGetXMLDesc(virNetworkPtr net,
2842                                unsigned int flags)
2843 {
2844     virNetworkObjPtr network;
2845     virNetworkDefPtr def;
2846     char *ret = NULL;
2847
2848     virCheckFlags(VIR_NETWORK_XML_INACTIVE, NULL);
2849
2850     if (!(network = networkObjFromNetwork(net)))
2851         return ret;
2852
2853     if (virNetworkGetXMLDescEnsureACL(net->conn, network->def) < 0)
2854         goto cleanup;
2855
2856     if ((flags & VIR_NETWORK_XML_INACTIVE) && network->newDef)
2857         def = network->newDef;
2858     else
2859         def = network->def;
2860
2861     ret = virNetworkDefFormat(def, flags);
2862
2863 cleanup:
2864     if (network)
2865         virNetworkObjUnlock(network);
2866     return ret;
2867 }
2868
2869 static char *networkGetBridgeName(virNetworkPtr net) {
2870     virNetworkObjPtr network;
2871     char *bridge = NULL;
2872
2873     if (!(network = networkObjFromNetwork(net)))
2874         return bridge;
2875
2876     if (virNetworkGetBridgeNameEnsureACL(net->conn, network->def) < 0)
2877         goto cleanup;
2878
2879     if (!(network->def->bridge)) {
2880         virReportError(VIR_ERR_INTERNAL_ERROR,
2881                        _("network '%s' does not have a bridge name."),
2882                        network->def->name);
2883         goto cleanup;
2884     }
2885
2886     ignore_value(VIR_STRDUP(bridge, network->def->bridge));
2887
2888 cleanup:
2889     if (network)
2890         virNetworkObjUnlock(network);
2891     return bridge;
2892 }
2893
2894 static int networkGetAutostart(virNetworkPtr net,
2895                              int *autostart) {
2896     virNetworkObjPtr network;
2897     int ret = -1;
2898
2899     if (!(network = networkObjFromNetwork(net)))
2900         return ret;
2901
2902     if (virNetworkGetAutostartEnsureACL(net->conn, network->def) < 0)
2903         goto cleanup;
2904
2905     *autostart = network->autostart;
2906     ret = 0;
2907
2908 cleanup:
2909     if (network)
2910         virNetworkObjUnlock(network);
2911     return ret;
2912 }
2913
2914 static int networkSetAutostart(virNetworkPtr net,
2915                                int autostart) {
2916     virNetworkDriverStatePtr driver = net->conn->networkPrivateData;
2917     virNetworkObjPtr network;
2918     char *configFile = NULL, *autostartLink = NULL;
2919     int ret = -1;
2920
2921     networkDriverLock(driver);
2922     network = virNetworkFindByUUID(&driver->networks, net->uuid);
2923
2924     if (!network) {
2925         virReportError(VIR_ERR_NO_NETWORK,
2926                        "%s", _("no network with matching uuid"));
2927         goto cleanup;
2928     }
2929
2930     if (virNetworkSetAutostartEnsureACL(net->conn, network->def) < 0)
2931         goto cleanup;
2932
2933     if (!network->persistent) {
2934         virReportError(VIR_ERR_OPERATION_INVALID,
2935                        "%s", _("cannot set autostart for transient network"));
2936         goto cleanup;
2937     }
2938
2939     autostart = (autostart != 0);
2940
2941     if (network->autostart != autostart) {
2942         if ((configFile = virNetworkConfigFile(driver->networkConfigDir, network->def->name)) == NULL)
2943             goto cleanup;
2944         if ((autostartLink = virNetworkConfigFile(driver->networkAutostartDir, network->def->name)) == NULL)
2945             goto cleanup;
2946
2947         if (autostart) {
2948             if (virFileMakePath(driver->networkAutostartDir) < 0) {
2949                 virReportSystemError(errno,
2950                                      _("cannot create autostart directory '%s'"),
2951                                      driver->networkAutostartDir);
2952                 goto cleanup;
2953             }
2954
2955             if (symlink(configFile, autostartLink) < 0) {
2956                 virReportSystemError(errno,
2957                                      _("Failed to create symlink '%s' to '%s'"),
2958                                      autostartLink, configFile);
2959                 goto cleanup;
2960             }
2961         } else {
2962             if (unlink(autostartLink) < 0 && errno != ENOENT && errno != ENOTDIR) {
2963                 virReportSystemError(errno,
2964                                      _("Failed to delete symlink '%s'"),
2965                                      autostartLink);
2966                 goto cleanup;
2967             }
2968         }
2969
2970         network->autostart = autostart;
2971     }
2972     ret = 0;
2973
2974 cleanup:
2975     VIR_FREE(configFile);
2976     VIR_FREE(autostartLink);
2977     if (network)
2978         virNetworkObjUnlock(network);
2979     networkDriverUnlock(driver);
2980     return ret;
2981 }
2982
2983
2984 static virNetworkDriver networkDriver = {
2985     "Network",
2986     .networkOpen = networkOpen, /* 0.2.0 */
2987     .networkClose = networkClose, /* 0.2.0 */
2988     .connectNumOfNetworks = networkConnectNumOfNetworks, /* 0.2.0 */
2989     .connectListNetworks = networkConnectListNetworks, /* 0.2.0 */
2990     .connectNumOfDefinedNetworks = networkConnectNumOfDefinedNetworks, /* 0.2.0 */
2991     .connectListDefinedNetworks = networkConnectListDefinedNetworks, /* 0.2.0 */
2992     .connectListAllNetworks = networkConnectListAllNetworks, /* 0.10.2 */
2993     .networkLookupByUUID = networkLookupByUUID, /* 0.2.0 */
2994     .networkLookupByName = networkLookupByName, /* 0.2.0 */
2995     .networkCreateXML = networkCreateXML, /* 0.2.0 */
2996     .networkDefineXML = networkDefineXML, /* 0.2.0 */
2997     .networkUndefine = networkUndefine, /* 0.2.0 */
2998     .networkUpdate = networkUpdate, /* 0.10.2 */
2999     .networkCreate = networkCreate, /* 0.2.0 */
3000     .networkDestroy = networkDestroy, /* 0.2.0 */
3001     .networkGetXMLDesc = networkGetXMLDesc, /* 0.2.0 */
3002     .networkGetBridgeName = networkGetBridgeName, /* 0.2.0 */
3003     .networkGetAutostart = networkGetAutostart, /* 0.2.1 */
3004     .networkSetAutostart = networkSetAutostart, /* 0.2.1 */
3005     .networkIsActive = networkIsActive, /* 0.7.3 */
3006     .networkIsPersistent = networkIsPersistent, /* 0.7.3 */
3007 };
3008
3009 static virStateDriver networkStateDriver = {
3010     .name = "Network",
3011     .stateInitialize  = networkStateInitialize,
3012     .stateAutoStart  = networkStateAutoStart,
3013     .stateCleanup = networkStateCleanup,
3014     .stateReload = networkStateReload,
3015 };
3016
3017 int networkRegister(void) {
3018     virRegisterNetworkDriver(&networkDriver);
3019     virRegisterStateDriver(&networkStateDriver);
3020     return 0;
3021 }
3022
3023 /********************************************************/
3024
3025 /* Private API to deal with logical switch capabilities.
3026  * These functions are exported so that other parts of libvirt can
3027  * call them, but are not part of the public API and not in the
3028  * driver's function table. If we ever have more than one network
3029  * driver, we will need to present these functions via a second
3030  * "backend" function table.
3031  */
3032
3033 /* networkCreateInterfacePool:
3034  * @netdef: the original NetDef from the network
3035  *
3036  * Creates an implicit interface pool of VF's when a PF dev is given
3037  */
3038 static int
3039 networkCreateInterfacePool(virNetworkDefPtr netdef) {
3040     unsigned int num_virt_fns = 0;
3041     char **vfname = NULL;
3042     virPCIDeviceAddressPtr *virt_fns;
3043     int ret = -1;
3044     size_t i;
3045
3046     if ((virNetDevGetVirtualFunctions(netdef->forward.pfs->dev,
3047                                       &vfname, &virt_fns, &num_virt_fns)) < 0) {
3048         virReportError(VIR_ERR_INTERNAL_ERROR,
3049                        _("Could not get Virtual functions on %s"),
3050                        netdef->forward.pfs->dev);
3051         goto finish;
3052     }
3053
3054     if (num_virt_fns == 0) {
3055         virReportError(VIR_ERR_INTERNAL_ERROR,
3056                        _("No Vf's present on SRIOV PF %s"),
3057                        netdef->forward.pfs->dev);
3058        goto finish;
3059     }
3060
3061     if (VIR_ALLOC_N(netdef->forward.ifs, num_virt_fns) < 0)
3062         goto finish;
3063
3064     netdef->forward.nifs = num_virt_fns;
3065
3066     for (i = 0; i < netdef->forward.nifs; i++) {
3067         if ((netdef->forward.type == VIR_NETWORK_FORWARD_BRIDGE) ||
3068             (netdef->forward.type == VIR_NETWORK_FORWARD_PRIVATE) ||
3069             (netdef->forward.type == VIR_NETWORK_FORWARD_VEPA) ||
3070             (netdef->forward.type == VIR_NETWORK_FORWARD_PASSTHROUGH)) {
3071             netdef->forward.ifs[i].type = VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_NETDEV;
3072             if (vfname[i]) {
3073                 if (VIR_STRDUP(netdef->forward.ifs[i].device.dev, vfname[i]) < 0)
3074                     goto finish;
3075             } else {
3076                 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
3077                                _("Direct mode types require interface names"));
3078                 goto finish;
3079             }
3080         }
3081         else if (netdef->forward.type == VIR_NETWORK_FORWARD_HOSTDEV) {
3082             /* VF's are always PCI devices */
3083             netdef->forward.ifs[i].type = VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_PCI;
3084             netdef->forward.ifs[i].device.pci.domain = virt_fns[i]->domain;
3085             netdef->forward.ifs[i].device.pci.bus = virt_fns[i]->bus;
3086             netdef->forward.ifs[i].device.pci.slot = virt_fns[i]->slot;
3087             netdef->forward.ifs[i].device.pci.function = virt_fns[i]->function;
3088         }
3089     }
3090
3091     ret = 0;
3092 finish:
3093     for (i = 0; i < num_virt_fns; i++) {
3094         VIR_FREE(vfname[i]);
3095         VIR_FREE(virt_fns[i]);
3096     }
3097     VIR_FREE(vfname);
3098     VIR_FREE(virt_fns);
3099     return ret;
3100 }
3101
3102 /* networkAllocateActualDevice:
3103  * @iface: the original NetDef from the domain
3104  *
3105  * Looks up the network reference by iface, allocates a physical
3106  * device from that network (if appropriate), and returns with the
3107  * virDomainActualNetDef filled in accordingly. If there are no
3108  * changes to be made in the netdef, then just leave the actualdef
3109  * empty.
3110  *
3111  * Returns 0 on success, -1 on failure.
3112  */
3113 int
3114 networkAllocateActualDevice(virDomainNetDefPtr iface)
3115 {
3116     virNetworkDriverStatePtr driver = driverState;
3117     enum virDomainNetType actualType = iface->type;
3118     virNetworkObjPtr network = NULL;
3119     virNetworkDefPtr netdef = NULL;
3120     virNetDevBandwidthPtr bandwidth = NULL;
3121     virPortGroupDefPtr portgroup = NULL;
3122     virNetDevVPortProfilePtr virtport = iface->virtPortProfile;
3123     virNetDevVlanPtr vlan = NULL;
3124     virNetworkForwardIfDefPtr dev = NULL;
3125     size_t i;
3126     int ret = -1;
3127
3128     if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK)
3129         goto validate;
3130
3131     virDomainActualNetDefFree(iface->data.network.actual);
3132     iface->data.network.actual = NULL;
3133
3134     networkDriverLock(driver);
3135     network = virNetworkFindByName(&driver->networks, iface->data.network.name);
3136     networkDriverUnlock(driver);
3137     if (!network) {
3138         virReportError(VIR_ERR_NO_NETWORK,
3139                        _("no network with matching name '%s'"),
3140                        iface->data.network.name);
3141         goto error;
3142     }
3143     netdef = network->def;
3144
3145     /* portgroup can be present for any type of network, in particular
3146      * for bandwidth information, so we need to check for that and
3147      * fill it in appropriately for all forward types.
3148     */
3149     portgroup = virPortGroupFindByName(netdef, iface->data.network.portgroup);
3150
3151     /* If there is already interface-specific bandwidth, just use that
3152      * (already in NetDef). Otherwise, if there is bandwidth info in
3153      * the portgroup, fill that into the ActualDef.
3154      */
3155
3156     if (iface->bandwidth)
3157         bandwidth = iface->bandwidth;
3158     else if (portgroup && portgroup->bandwidth)
3159         bandwidth = portgroup->bandwidth;
3160
3161     if (bandwidth) {
3162         if (!iface->data.network.actual &&
3163             VIR_ALLOC(iface->data.network.actual) < 0)
3164             goto error;
3165         if (virNetDevBandwidthCopy(&iface->data.network.actual->bandwidth,
3166                                    bandwidth) < 0)
3167             goto error;
3168     }
3169
3170     /* copy appropriate vlan info to actualNet */
3171     if (iface->vlan.nTags > 0)
3172         vlan = &iface->vlan;
3173     else if (portgroup && portgroup->vlan.nTags > 0)
3174         vlan = &portgroup->vlan;
3175     else if (netdef->vlan.nTags > 0)
3176         vlan = &netdef->vlan;
3177
3178     if (vlan) {
3179         if (!iface->data.network.actual &&
3180             VIR_ALLOC(iface->data.network.actual) < 0)
3181             goto error;
3182         if (virNetDevVlanCopy(&iface->data.network.actual->vlan, vlan) < 0)
3183            goto error;
3184     }
3185
3186     if ((netdef->forward.type == VIR_NETWORK_FORWARD_NONE) ||
3187         (netdef->forward.type == VIR_NETWORK_FORWARD_NAT) ||
3188         (netdef->forward.type == VIR_NETWORK_FORWARD_ROUTE)) {
3189         /* for these forward types, the actual net type really *is*
3190          *NETWORK; we just keep the info from the portgroup in
3191          * iface->data.network.actual
3192         */
3193         if (iface->data.network.actual)
3194             iface->data.network.actual->type = VIR_DOMAIN_NET_TYPE_NETWORK;
3195
3196         if (networkPlugBandwidth(network, iface) < 0)
3197             goto error;
3198
3199     } else if ((netdef->forward.type == VIR_NETWORK_FORWARD_BRIDGE) &&
3200                netdef->bridge) {
3201
3202         /* <forward type='bridge'/> <bridge name='xxx'/>
3203          * is VIR_DOMAIN_NET_TYPE_BRIDGE
3204          */
3205
3206         if (!iface->data.network.actual &&
3207             VIR_ALLOC(iface->data.network.actual) < 0)
3208             goto error;
3209
3210         iface->data.network.actual->type = actualType = VIR_DOMAIN_NET_TYPE_BRIDGE;
3211         if (VIR_STRDUP(iface->data.network.actual->data.bridge.brname,
3212                        netdef->bridge) < 0)
3213             goto error;
3214
3215         /* merge virtualports from interface, network, and portgroup to
3216          * arrive at actual virtualport to use
3217          */
3218         if (virNetDevVPortProfileMerge3(&iface->data.network.actual->virtPortProfile,
3219                                         iface->virtPortProfile,
3220                                         netdef->virtPortProfile,
3221                                         portgroup
3222                                         ? portgroup->virtPortProfile : NULL) < 0) {
3223             goto error;
3224         }
3225         virtport = iface->data.network.actual->virtPortProfile;
3226         if (virtport) {
3227             /* only type='openvswitch' is allowed for bridges */
3228             if (virtport->virtPortType != VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH) {
3229                 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
3230                                _("<virtualport type='%s'> not supported for network "
3231                                  "'%s' which uses a bridge device"),
3232                                virNetDevVPortTypeToString(virtport->virtPortType),
3233                                netdef->name);
3234                 goto error;
3235             }
3236         }
3237
3238     } else if (netdef->forward.type == VIR_NETWORK_FORWARD_HOSTDEV) {
3239
3240         virDomainHostdevSubsysPciBackendType backend;
3241
3242         if (!iface->data.network.actual &&
3243             VIR_ALLOC(iface->data.network.actual) < 0)
3244             goto error;
3245
3246         iface->data.network.actual->type = actualType = VIR_DOMAIN_NET_TYPE_HOSTDEV;
3247         if (netdef->forward.npfs > 0 && netdef->forward.nifs <= 0 &&
3248             networkCreateInterfacePool(netdef) < 0) {
3249             goto error;
3250         }
3251
3252         /* pick first dev with 0 connections */
3253         for (i = 0; i < netdef->forward.nifs; i++) {
3254             if (netdef->forward.ifs[i].connections == 0) {
3255                 dev = &netdef->forward.ifs[i];
3256                 break;
3257             }
3258         }
3259         if (!dev) {
3260             virReportError(VIR_ERR_INTERNAL_ERROR,
3261                            _("network '%s' requires exclusive access "
3262                              "to interfaces, but none are available"),
3263                            netdef->name);
3264             goto error;
3265         }
3266         iface->data.network.actual->data.hostdev.def.parent.type = VIR_DOMAIN_DEVICE_NET;
3267         iface->data.network.actual->data.hostdev.def.parent.data.net = iface;
3268         iface->data.network.actual->data.hostdev.def.info = &iface->info;
3269         iface->data.network.actual->data.hostdev.def.mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
3270         iface->data.network.actual->data.hostdev.def.managed = netdef->forward.managed ? 1 : 0;
3271         iface->data.network.actual->data.hostdev.def.source.subsys.type = dev->type;
3272         iface->data.network.actual->data.hostdev.def.source.subsys.u.pci.addr = dev->device.pci;
3273
3274         switch (netdef->forward.driverName)
3275         {
3276         case VIR_NETWORK_FORWARD_DRIVER_NAME_DEFAULT:
3277             backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT;
3278             break;
3279         case VIR_NETWORK_FORWARD_DRIVER_NAME_KVM:
3280             backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM;
3281             break;
3282         case VIR_NETWORK_FORWARD_DRIVER_NAME_VFIO:
3283             backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO;
3284             break;
3285         default:
3286             virReportError(VIR_ERR_INTERNAL_ERROR,
3287                            _("unrecognized driver name value %d "
3288                              " in network '%s'"),
3289                            netdef->forward.driverName, netdef->name);
3290             goto error;
3291         }
3292         iface->data.network.actual->data.hostdev.def.source.subsys.u.pci.backend
3293             = backend;
3294
3295         /* merge virtualports from interface, network, and portgroup to
3296          * arrive at actual virtualport to use
3297          */
3298         if (virNetDevVPortProfileMerge3(&iface->data.network.actual->virtPortProfile,
3299                                         iface->virtPortProfile,
3300                                         netdef->virtPortProfile,
3301                                         portgroup
3302                                         ? portgroup->virtPortProfile : NULL) < 0) {
3303             goto error;
3304         }
3305         virtport = iface->data.network.actual->virtPortProfile;
3306         if (virtport) {
3307             /* make sure type is supported for hostdev connections */
3308             if (virtport->virtPortType != VIR_NETDEV_VPORT_PROFILE_8021QBG &&
3309                 virtport->virtPortType != VIR_NETDEV_VPORT_PROFILE_8021QBH) {
3310                 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
3311                                _("<virtualport type='%s'> not supported for network "
3312                                  "'%s' which uses an SR-IOV Virtual Function "
3313                                  "via PCI passthrough"),
3314                                virNetDevVPortTypeToString(virtport->virtPortType),
3315                                netdef->name);
3316                 goto error;
3317             }
3318         }
3319
3320     } else if ((netdef->forward.type == VIR_NETWORK_FORWARD_BRIDGE) ||
3321                (netdef->forward.type == VIR_NETWORK_FORWARD_PRIVATE) ||
3322                (netdef->forward.type == VIR_NETWORK_FORWARD_VEPA) ||
3323                (netdef->forward.type == VIR_NETWORK_FORWARD_PASSTHROUGH)) {
3324
3325         /* <forward type='bridge|private|vepa|passthrough'> are all
3326          * VIR_DOMAIN_NET_TYPE_DIRECT.
3327          */
3328
3329         if (!iface->data.network.actual &&
3330             VIR_ALLOC(iface->data.network.actual) < 0)
3331             goto error;
3332
3333         /* Set type=direct and appropriate <source mode='xxx'/> */
3334         iface->data.network.actual->type = actualType = VIR_DOMAIN_NET_TYPE_DIRECT;
3335         switch (netdef->forward.type) {
3336         case VIR_NETWORK_FORWARD_BRIDGE:
3337             iface->data.network.actual->data.direct.mode = VIR_NETDEV_MACVLAN_MODE_BRIDGE;
3338             break;
3339         case VIR_NETWORK_FORWARD_PRIVATE:
3340             iface->data.network.actual->data.direct.mode = VIR_NETDEV_MACVLAN_MODE_PRIVATE;
3341             break;
3342         case VIR_NETWORK_FORWARD_VEPA:
3343             iface->data.network.actual->data.direct.mode = VIR_NETDEV_MACVLAN_MODE_VEPA;
3344             break;
3345         case VIR_NETWORK_FORWARD_PASSTHROUGH:
3346             iface->data.network.actual->data.direct.mode = VIR_NETDEV_MACVLAN_MODE_PASSTHRU;
3347             break;
3348         }
3349
3350         /* merge virtualports from interface, network, and portgroup to
3351          * arrive at actual virtualport to use
3352          */
3353         if (virNetDevVPortProfileMerge3(&iface->data.network.actual->virtPortProfile,
3354                                         iface->virtPortProfile,
3355                                         netdef->virtPortProfile,
3356                                         portgroup
3357                                         ? portgroup->virtPortProfile : NULL) < 0) {
3358             goto error;
3359         }
3360         virtport = iface->data.network.actual->virtPortProfile;
3361         if (virtport) {
3362             /* make sure type is supported for macvtap connections */
3363             if (virtport->virtPortType != VIR_NETDEV_VPORT_PROFILE_8021QBG &&
3364                 virtport->virtPortType != VIR_NETDEV_VPORT_PROFILE_8021QBH) {
3365                 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
3366                                _("<virtualport type='%s'> not supported for network "
3367                                  "'%s' which uses a macvtap device"),
3368                                virNetDevVPortTypeToString(virtport->virtPortType),
3369                                netdef->name);
3370                 goto error;
3371             }
3372         }
3373
3374         /* If there is only a single device, just return it (caller will detect
3375          * any error if exclusive use is required but could not be acquired).
3376          */
3377         if ((netdef->forward.nifs <= 0) && (netdef->forward.npfs <= 0)) {
3378             virReportError(VIR_ERR_INTERNAL_ERROR,
3379                            _("network '%s' uses a direct mode, but "
3380                              "has no forward dev and no interface pool"),
3381                            netdef->name);
3382             goto error;
3383         } else {
3384             /* pick an interface from the pool */
3385
3386             if (netdef->forward.npfs > 0 && netdef->forward.nifs == 0 &&
3387                 networkCreateInterfacePool(netdef) < 0) {
3388                 goto error;
3389             }
3390
3391             /* PASSTHROUGH mode, and PRIVATE Mode + 802.1Qbh both
3392              * require exclusive access to a device, so current
3393              * connections count must be 0.  Other modes can share, so
3394              * just search for the one with the lowest number of
3395              * connections.
3396              */
3397             if ((netdef->forward.type == VIR_NETWORK_FORWARD_PASSTHROUGH) ||
3398                 ((netdef->forward.type == VIR_NETWORK_FORWARD_PRIVATE) &&
3399                  iface->data.network.actual->virtPortProfile &&
3400                  (iface->data.network.actual->virtPortProfile->virtPortType
3401                   == VIR_NETDEV_VPORT_PROFILE_8021QBH))) {
3402
3403                 /* pick first dev with 0 connections */
3404                 for (i = 0; i < netdef->forward.nifs; i++) {
3405                     if (netdef->forward.ifs[i].connections == 0) {
3406                         dev = &netdef->forward.ifs[i];
3407                         break;
3408                     }
3409                 }
3410             } else {
3411                 /* pick least used dev */
3412                 dev = &netdef->forward.ifs[0];
3413                 for (i = 1; i < netdef->forward.nifs; i++) {
3414                     if (netdef->forward.ifs[i].connections < dev->connections)
3415                         dev = &netdef->forward.ifs[i];
3416                 }
3417             }
3418             /* dev points at the physical device we want to use */
3419             if (!dev) {
3420                 virReportError(VIR_ERR_INTERNAL_ERROR,
3421                                _("network '%s' requires exclusive access "
3422                                  "to interfaces, but none are available"),
3423                                netdef->name);
3424                 goto error;
3425             }
3426             if (VIR_STRDUP(iface->data.network.actual->data.direct.linkdev,
3427                            dev->device.dev) < 0)
3428                 goto error;
3429         }
3430     }
3431
3432     if (virNetDevVPortProfileCheckComplete(virtport, true) < 0)
3433         goto error;
3434
3435 validate:
3436     /* make sure that everything now specified for the device is
3437      * actually supported on this type of network. NB: network,
3438      * netdev, and iface->data.network.actual may all be NULL.
3439      */
3440
3441     if (virDomainNetGetActualVlan(iface)) {
3442         /* vlan configuration via libvirt is only supported for
3443          * PCI Passthrough SR-IOV devices and openvswitch bridges.
3444          * otherwise log an error and fail
3445          */
3446         if (!(actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV ||
3447               (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE &&
3448                virtport && virtport->virtPortType
3449                == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH))) {
3450             if (netdef) {
3451                 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
3452                                _("an interface connecting to network '%s' "
3453                                  "is requesting a vlan tag, but that is not "
3454                                  "supported for this type of network"),
3455                                netdef->name);
3456             } else {
3457                 virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
3458                                _("an interface of type '%s' "
3459                                  "is requesting a vlan tag, but that is not "
3460                                  "supported for this type of connection"),
3461                                virDomainNetTypeToString(iface->type));
3462             }
3463             goto error;
3464         }
3465     }
3466
3467     if (dev) {
3468         /* we are now assured of success, so mark the allocation */
3469         dev->connections++;
3470         if (actualType != VIR_DOMAIN_NET_TYPE_HOSTDEV) {
3471             VIR_DEBUG("Using physical device %s, %d connections",
3472                       dev->device.dev, dev->connections);
3473         } else {
3474             VIR_DEBUG("Using physical device %04x:%02x:%02x.%x, connections %d",
3475                       dev->device.pci.domain, dev->device.pci.bus,
3476                       dev->device.pci.slot, dev->device.pci.function,
3477                       dev->connections);
3478         }
3479     }
3480
3481     if (netdef) {
3482         netdef->connections++;
3483         VIR_DEBUG("Using network %s, %d connections",
3484                   netdef->name, netdef->connections);
3485     }
3486     ret = 0;
3487
3488 cleanup:
3489     if (network)
3490         virNetworkObjUnlock(network);
3491     return ret;
3492
3493 error:
3494     if (iface->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
3495         virDomainActualNetDefFree(iface->data.network.actual);
3496         iface->data.network.actual = NULL;
3497     }
3498     goto cleanup;
3499 }
3500
3501 /* networkNotifyActualDevice:
3502  * @iface:  the domain's NetDef with an "actual" device already filled in.
3503  *
3504  * Called to notify the network driver when libvirtd is restarted and
3505  * finds an already running domain. If appropriate it will force an
3506  * allocation of the actual->direct.linkdev to get everything back in
3507  * order.
3508  *
3509  * Returns 0 on success, -1 on failure.
3510  */
3511 int
3512 networkNotifyActualDevice(virDomainNetDefPtr iface)
3513 {
3514     virNetworkDriverStatePtr driver = driverState;
3515     enum virDomainNetType actualType = virDomainNetGetActualType(iface);
3516     virNetworkObjPtr network;
3517     virNetworkDefPtr netdef;
3518     virNetworkForwardIfDefPtr dev = NULL;
3519     size_t i;
3520     int ret = -1;
3521
3522     if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK)
3523        return 0;
3524
3525     networkDriverLock(driver);
3526     network = virNetworkFindByName(&driver->networks, iface->data.network.name);
3527     networkDriverUnlock(driver);
3528     if (!network) {
3529         virReportError(VIR_ERR_NO_NETWORK,
3530                        _("no network with matching name '%s'"),
3531                        iface->data.network.name);
3532         goto error;
3533     }
3534     netdef = network->def;
3535
3536     if (!iface->data.network.actual ||
3537         (actualType != VIR_DOMAIN_NET_TYPE_DIRECT &&
3538          actualType != VIR_DOMAIN_NET_TYPE_HOSTDEV)) {
3539         VIR_DEBUG("Nothing to claim from network %s", iface->data.network.name);
3540         goto success;
3541     }
3542
3543     if (netdef->forward.npfs > 0 && netdef->forward.nifs == 0 &&
3544         networkCreateInterfacePool(netdef) < 0) {
3545         goto error;
3546     }
3547     if (netdef->forward.nifs == 0) {
3548         virReportError(VIR_ERR_INTERNAL_ERROR,
3549                        _("network '%s' uses a direct or hostdev mode, "
3550                          "but has no forward dev and no interface pool"),
3551                        netdef->name);
3552         goto error;
3553     }
3554
3555     if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
3556         const char *actualDev;
3557
3558         actualDev = virDomainNetGetActualDirectDev(iface);
3559         if (!actualDev) {
3560             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
3561                            _("the interface uses a direct mode, "
3562                              "but has no source dev"));
3563             goto error;
3564         }
3565
3566         /* find the matching interface and increment its connections */
3567         for (i = 0; i < netdef->forward.nifs; i++) {
3568             if (netdef->forward.ifs[i].type
3569                 == VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_NETDEV &&
3570                 STREQ(actualDev, netdef->forward.ifs[i].device.dev)) {
3571                 dev = &netdef->forward.ifs[i];
3572                 break;
3573             }
3574         }
3575         /* dev points at the physical device we want to use */
3576         if (!dev) {
3577             virReportError(VIR_ERR_INTERNAL_ERROR,
3578                            _("network '%s' doesn't have dev='%s' "
3579                              "in use by domain"),
3580                            netdef->name, actualDev);
3581             goto error;
3582         }
3583
3584         /* PASSTHROUGH mode and PRIVATE Mode + 802.1Qbh both require
3585          * exclusive access to a device, so current connections count
3586          * must be 0 in those cases.
3587          */
3588         if ((dev->connections > 0) &&
3589             ((netdef->forward.type == VIR_NETWORK_FORWARD_PASSTHROUGH) ||
3590              ((netdef->forward.type == VIR_NETWORK_FORWARD_PRIVATE) &&
3591               iface->data.network.actual->virtPortProfile &&
3592               (iface->data.network.actual->virtPortProfile->virtPortType
3593                == VIR_NETDEV_VPORT_PROFILE_8021QBH)))) {
3594             virReportError(VIR_ERR_INTERNAL_ERROR,
3595                            _("network '%s' claims dev='%s' is already in "
3596                              "use by a different domain"),
3597                            netdef->name, actualDev);
3598             goto error;
3599         }
3600
3601         /* we are now assured of success, so mark the allocation */
3602         dev->connections++;
3603         VIR_DEBUG("Using physical device %s, connections %d",
3604                   dev->device.dev, dev->connections);
3605
3606     }  else /* if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) */ {
3607         virDomainHostdevDefPtr hostdev;
3608
3609         hostdev = virDomainNetGetActualHostdev(iface);
3610         if (!hostdev) {
3611             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
3612                            _("the interface uses a hostdev mode, "
3613                              "but has no hostdev"));
3614             goto error;
3615         }
3616
3617         /* find the matching interface and increment its connections */
3618         for (i = 0; i < netdef->forward.nifs; i++) {
3619             if (netdef->forward.ifs[i].type
3620                 == VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_PCI &&
3621                 virDevicePCIAddressEqual(&hostdev->source.subsys.u.pci.addr,
3622                                          &netdef->forward.ifs[i].device.pci)) {
3623                 dev = &netdef->forward.ifs[i];
3624                 break;
3625             }
3626         }
3627         /* dev points at the physical device we want to use */
3628         if (!dev) {
3629             virReportError(VIR_ERR_INTERNAL_ERROR,
3630                            _("network '%s' doesn't have "
3631                              "PCI device %04x:%02x:%02x.%x in use by domain"),
3632                            netdef->name,
3633                            hostdev->source.subsys.u.pci.addr.domain,
3634                            hostdev->source.subsys.u.pci.addr.bus,
3635                            hostdev->source.subsys.u.pci.addr.slot,
3636                            hostdev->source.subsys.u.pci.addr.function);
3637                 goto error;
3638         }
3639
3640         /* PASSTHROUGH mode, PRIVATE Mode + 802.1Qbh, and hostdev (PCI
3641          * passthrough) all require exclusive access to a device, so
3642          * current connections count must be 0 in those cases.
3643          */
3644         if ((dev->connections > 0) &&
3645             netdef->forward.type == VIR_NETWORK_FORWARD_HOSTDEV) {
3646             virReportError(VIR_ERR_INTERNAL_ERROR,
3647                            _("network '%s' claims the PCI device at "
3648                              "domain=%d bus=%d slot=%d function=%d "
3649                              "is already in use by a different domain"),
3650                            netdef->name,
3651                            dev->device.pci.domain, dev->device.pci.bus,
3652                            dev->device.pci.slot, dev->device.pci.function);
3653             goto error;
3654         }
3655
3656         /* we are now assured of success, so mark the allocation */
3657         dev->connections++;
3658         VIR_DEBUG("Using physical device %04x:%02x:%02x.%x, connections %d",
3659                   dev->device.pci.domain, dev->device.pci.bus,
3660                   dev->device.pci.slot, dev->device.pci.function,
3661                   dev->connections);
3662     }
3663
3664 success:
3665     netdef->connections++;
3666     VIR_DEBUG("Using network %s, %d connections",
3667               netdef->name, netdef->connections);
3668     ret = 0;
3669 cleanup:
3670     if (network)
3671         virNetworkObjUnlock(network);
3672     return ret;
3673
3674 error:
3675     goto cleanup;
3676 }
3677
3678
3679 /* networkReleaseActualDevice:
3680  * @iface:  a domain's NetDef (interface definition)
3681  *
3682  * Given a domain <interface> element that previously had its <actual>
3683  * element filled in (and possibly a physical device allocated to it),
3684  * free up the physical device for use by someone else, and free the
3685  * virDomainActualNetDef.
3686  *
3687  * Returns 0 on success, -1 on failure.
3688  */
3689 int
3690 networkReleaseActualDevice(virDomainNetDefPtr iface)
3691 {
3692     virNetworkDriverStatePtr driver = driverState;
3693     enum virDomainNetType actualType = virDomainNetGetActualType(iface);
3694     virNetworkObjPtr network;
3695     virNetworkDefPtr netdef;
3696     virNetworkForwardIfDefPtr dev = NULL;
3697     size_t i;
3698     int ret = -1;
3699
3700     if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK)
3701        return 0;
3702
3703     networkDriverLock(driver);
3704     network = virNetworkFindByName(&driver->networks, iface->data.network.name);
3705     networkDriverUnlock(driver);
3706     if (!network) {
3707         virReportError(VIR_ERR_NO_NETWORK,
3708                        _("no network with matching name '%s'"),
3709                        iface->data.network.name);
3710         goto error;
3711     }
3712     netdef = network->def;
3713
3714     if ((netdef->forward.type == VIR_NETWORK_FORWARD_NONE ||
3715          netdef->forward.type == VIR_NETWORK_FORWARD_NAT ||
3716          netdef->forward.type == VIR_NETWORK_FORWARD_ROUTE) &&
3717         networkUnplugBandwidth(network, iface) < 0)
3718         goto error;
3719
3720     if ((!iface->data.network.actual) ||
3721         ((actualType != VIR_DOMAIN_NET_TYPE_DIRECT) &&
3722          (actualType != VIR_DOMAIN_NET_TYPE_HOSTDEV))) {
3723         VIR_DEBUG("Nothing to release to network %s", iface->data.network.name);
3724         goto success;
3725     }
3726
3727     if (netdef->forward.nifs == 0) {
3728         virReportError(VIR_ERR_INTERNAL_ERROR,
3729                        _("network '%s' uses a direct/hostdev mode, but "
3730                          "has no forward dev and no interface pool"),
3731                        netdef->name);
3732         goto error;
3733     }
3734
3735     if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
3736         const char *actualDev;
3737
3738         actualDev = virDomainNetGetActualDirectDev(iface);
3739         if (!actualDev) {
3740             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
3741                            _("the interface uses a direct mode, "
3742                              "but has no source dev"));
3743             goto error;
3744         }
3745
3746         for (i = 0; i < netdef->forward.nifs; i++) {
3747             if (netdef->forward.ifs[i].type
3748                 == VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_NETDEV &&
3749                 STREQ(actualDev, netdef->forward.ifs[i].device.dev)) {
3750                 dev = &netdef->forward.ifs[i];
3751                 break;
3752             }
3753         }
3754
3755         if (!dev) {
3756             virReportError(VIR_ERR_INTERNAL_ERROR,
3757                            _("network '%s' doesn't have dev='%s' "
3758                              "in use by domain"),
3759                            netdef->name, actualDev);
3760             goto error;
3761         }
3762
3763         dev->connections--;
3764         VIR_DEBUG("Releasing physical device %s, connections %d",
3765                   dev->device.dev, dev->connections);
3766
3767     } else /* if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) */ {
3768         virDomainHostdevDefPtr hostdev;
3769
3770         hostdev = virDomainNetGetActualHostdev(iface);
3771         if (!hostdev) {
3772             virReportError(VIR_ERR_INTERNAL_ERROR,
3773                            "%s", _("the interface uses a hostdev mode, but has no hostdev"));
3774             goto error;
3775         }
3776
3777         for (i = 0; i < netdef->forward.nifs; i++) {
3778             if (netdef->forward.ifs[i].type
3779                 == VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_PCI &&
3780                 virDevicePCIAddressEqual(&hostdev->source.subsys.u.pci.addr,
3781                                          &netdef->forward.ifs[i].device.pci)) {
3782                 dev = &netdef->forward.ifs[i];
3783                 break;
3784             }
3785         }
3786
3787         if (!dev) {
3788             virReportError(VIR_ERR_INTERNAL_ERROR,
3789                            _("network '%s' doesn't have "
3790                              "PCI device %04x:%02x:%02x.%x in use by domain"),
3791                            netdef->name,
3792                            hostdev->source.subsys.u.pci.addr.domain,
3793                            hostdev->source.subsys.u.pci.addr.bus,
3794                            hostdev->source.subsys.u.pci.addr.slot,
3795                            hostdev->source.subsys.u.pci.addr.function);
3796                 goto error;
3797         }
3798
3799         dev->connections--;
3800         VIR_DEBUG("Releasing physical device %04x:%02x:%02x.%x, connections %d",
3801                   dev->device.pci.domain, dev->device.pci.bus,
3802                   dev->device.pci.slot, dev->device.pci.function,
3803                   dev->connections);
3804    }
3805
3806 success:
3807     netdef->connections--;
3808     VIR_DEBUG("Releasing network %s, %d connections",
3809               netdef->name, netdef->connections);
3810     ret = 0;
3811 cleanup:
3812     if (network)
3813         virNetworkObjUnlock(network);
3814     if (iface->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
3815         virDomainActualNetDefFree(iface->data.network.actual);
3816         iface->data.network.actual = NULL;
3817     }
3818     return ret;
3819
3820 error:
3821     goto cleanup;
3822 }
3823
3824 /*
3825  * networkGetNetworkAddress:
3826  * @netname: the name of a network
3827  * @netaddr: string representation of IP address for that network.
3828  *
3829  * Attempt to return an IP (v4) address associated with the named
3830  * network. If a libvirt virtual network, that will be provided in the
3831  * configuration. For host bridge and direct (macvtap) networks, we
3832  * must do an ioctl to learn the address.
3833  *
3834  * Note: This function returns the 1st IPv4 address it finds. It might
3835  * be useful if it was more flexible, but the current use (getting a
3836  * listen address for qemu's vnc/spice graphics server) can only use a
3837  * single address anyway.
3838  *
3839  * Returns 0 on success, and puts a string (which must be free'd by
3840  * the caller) into *netaddr. Returns -1 on failure or -2 if
3841  * completely unsupported.
3842  */
3843 int
3844 networkGetNetworkAddress(const char *netname, char **netaddr)
3845 {
3846     int ret = -1;
3847     virNetworkDriverStatePtr driver = driverState;
3848     virNetworkObjPtr network;
3849     virNetworkDefPtr netdef;
3850     virNetworkIpDefPtr ipdef;
3851     virSocketAddr addr;
3852     virSocketAddrPtr addrptr = NULL;
3853     char *dev_name = NULL;
3854
3855     *netaddr = NULL;
3856     networkDriverLock(driver);
3857     network = virNetworkFindByName(&driver->networks, netname);
3858     networkDriverUnlock(driver);
3859     if (!network) {
3860         virReportError(VIR_ERR_NO_NETWORK,
3861                        _("no network with matching name '%s'"),
3862                        netname);
3863         goto error;
3864     }
3865     netdef = network->def;
3866
3867     switch (netdef->forward.type) {
3868     case VIR_NETWORK_FORWARD_NONE:
3869     case VIR_NETWORK_FORWARD_NAT:
3870     case VIR_NETWORK_FORWARD_ROUTE:
3871         /* if there's an ipv4def, get it's address */
3872         ipdef = virNetworkDefGetIpByIndex(netdef, AF_INET, 0);
3873         if (!ipdef) {
3874             virReportError(VIR_ERR_INTERNAL_ERROR,
3875                            _("network '%s' doesn't have an IPv4 address"),
3876                            netdef->name);
3877             break;
3878         }
3879         addrptr = &ipdef->address;
3880         break;
3881
3882     case VIR_NETWORK_FORWARD_BRIDGE:
3883         if ((dev_name = netdef->bridge))
3884             break;
3885         /*
3886          * fall through if netdef->bridge wasn't set, since this is
3887          * also a direct-mode interface.
3888          */
3889     case VIR_NETWORK_FORWARD_PRIVATE:
3890     case VIR_NETWORK_FORWARD_VEPA:
3891     case VIR_NETWORK_FORWARD_PASSTHROUGH:
3892         if ((netdef->forward.nifs > 0) && netdef->forward.ifs)
3893             dev_name = netdef->forward.ifs[0].device.dev;
3894
3895         if (!dev_name) {
3896             virReportError(VIR_ERR_INTERNAL_ERROR,
3897                            _("network '%s' has no associated interface or bridge"),
3898                            netdef->name);
3899         }
3900         break;
3901     }
3902
3903     if (dev_name) {
3904         if (virNetDevGetIPv4Address(dev_name, &addr) < 0)
3905             goto error;
3906         addrptr = &addr;
3907     }
3908
3909     if (!(addrptr &&
3910           (*netaddr = virSocketAddrFormat(addrptr)))) {
3911         goto error;
3912     }
3913