2
* bridge_driver.c: core driver methods for managing network
4
* Copyright (C) 2006-2011 Red Hat, Inc.
5
* Copyright (C) 2006 Daniel P. Berrange
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.
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.
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this library; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
* Author: Daniel P. Berrange <berrange@redhat.com>
26
#include <sys/types.h>
36
#include <sys/utsname.h>
44
#include <sys/ioctl.h>
46
#include "virterror_internal.h"
47
#include "datatypes.h"
48
#include "bridge_driver.h"
49
#include "network_conf.h"
61
#include "util/network.h"
62
#include "configmake.h"
64
#define NETWORK_PID_DIR LOCALSTATEDIR "/run/libvirt/network"
65
#define NETWORK_STATE_DIR LOCALSTATEDIR "/lib/libvirt/network"
67
#define DNSMASQ_STATE_DIR LOCALSTATEDIR "/lib/libvirt/dnsmasq"
68
#define RADVD_STATE_DIR LOCALSTATEDIR "/lib/libvirt/radvd"
70
#define VIR_FROM_THIS VIR_FROM_NETWORK
72
#define networkReportError(code, ...) \
73
virReportErrorHelper(NULL, VIR_FROM_NETWORK, code, __FILE__, \
74
__FUNCTION__, __LINE__, __VA_ARGS__)
76
/* Main driver state */
77
struct network_driver {
80
virNetworkObjList networks;
82
iptablesContext *iptables;
84
char *networkConfigDir;
85
char *networkAutostartDir;
90
static void networkDriverLock(struct network_driver *driver)
92
virMutexLock(&driver->lock);
94
static void networkDriverUnlock(struct network_driver *driver)
96
virMutexUnlock(&driver->lock);
99
static int networkShutdown(void);
101
static int networkStartNetworkDaemon(struct network_driver *driver,
102
virNetworkObjPtr network);
104
static int networkShutdownNetworkDaemon(struct network_driver *driver,
105
virNetworkObjPtr network);
107
static void networkReloadIptablesRules(struct network_driver *driver);
109
static struct network_driver *driverState = NULL;
112
networkRadvdPidfileBasename(const char *netname)
114
/* this is simple but we want to be sure it's consistently done */
117
virAsprintf(&pidfilebase, "%s-radvd", netname);
122
networkRadvdConfigFileName(const char *netname)
126
virAsprintf(&configfile, RADVD_STATE_DIR "/%s-radvd.conf",
132
networkFindActiveConfigs(struct network_driver *driver) {
135
for (i = 0 ; i < driver->networks.count ; i++) {
136
virNetworkObjPtr obj = driver->networks.objs[i];
137
virNetworkDefPtr tmp;
140
virNetworkObjLock(obj);
142
if ((config = virNetworkConfigFile(NETWORK_STATE_DIR,
143
obj->def->name)) == NULL) {
144
virNetworkObjUnlock(obj);
148
if (access(config, R_OK) < 0) {
150
virNetworkObjUnlock(obj);
154
/* Try and load the live config */
155
tmp = virNetworkDefParseFile(config);
158
obj->newDef = obj->def;
162
/* If bridge exists, then mark it active */
163
if (obj->def->bridge &&
164
brHasBridge(driver->brctl, obj->def->bridge) == 0) {
167
/* Try and read dnsmasq/radvd pids if any */
168
if (obj->def->ips && (obj->def->nips > 0)) {
169
char *pidpath, *radvdpidbase;
171
if (virFileReadPid(NETWORK_PID_DIR, obj->def->name,
172
&obj->dnsmasqPid) == 0) {
173
/* Check that it's still alive */
174
if (kill(obj->dnsmasqPid, 0) != 0)
175
obj->dnsmasqPid = -1;
176
if (virAsprintf(&pidpath, "/proc/%d/exe", obj->dnsmasqPid) < 0) {
180
if (virFileLinkPointsTo(pidpath, DNSMASQ) == 0)
181
obj->dnsmasqPid = -1;
185
if (!(radvdpidbase = networkRadvdPidfileBasename(obj->def->name))) {
189
if (virFileReadPid(NETWORK_PID_DIR, radvdpidbase,
190
&obj->radvdPid) == 0) {
191
/* Check that it's still alive */
192
if (kill(obj->radvdPid, 0) != 0)
194
if (virAsprintf(&pidpath, "/proc/%d/exe", obj->radvdPid) < 0) {
196
VIR_FREE(radvdpidbase);
199
if (virFileLinkPointsTo(pidpath, RADVD) == 0)
203
VIR_FREE(radvdpidbase);
208
virNetworkObjUnlock(obj);
214
networkAutostartConfigs(struct network_driver *driver) {
217
for (i = 0 ; i < driver->networks.count ; i++) {
218
virNetworkObjLock(driver->networks.objs[i]);
219
if (driver->networks.objs[i]->autostart &&
220
!virNetworkObjIsActive(driver->networks.objs[i]) &&
221
networkStartNetworkDaemon(driver, driver->networks.objs[i]) < 0) {
222
/* failed to start but already logged */
224
virNetworkObjUnlock(driver->networks.objs[i]);
231
* Initialization function for the QEmu daemon
234
networkStartup(int privileged) {
235
uid_t uid = geteuid();
239
if (VIR_ALLOC(driverState) < 0)
242
if (virMutexInit(&driverState->lock) < 0) {
243
VIR_FREE(driverState);
246
networkDriverLock(driverState);
249
if (virAsprintf(&driverState->logDir,
250
"%s/log/libvirt/qemu", LOCALSTATEDIR) == -1)
253
if ((base = strdup (SYSCONFDIR "/libvirt")) == NULL)
256
char *userdir = virGetUserDirectory(uid);
261
if (virAsprintf(&driverState->logDir,
262
"%s/.libvirt/qemu/log", userdir) == -1) {
267
if (virAsprintf(&base, "%s/.libvirt", userdir) == -1) {
274
/* Configuration paths are either ~/.libvirt/qemu/... (session) or
275
* /etc/libvirt/qemu/... (system).
277
if (virAsprintf(&driverState->networkConfigDir, "%s/qemu/networks", base) == -1)
280
if (virAsprintf(&driverState->networkAutostartDir, "%s/qemu/networks/autostart",
286
if ((err = brInit(&driverState->brctl))) {
287
virReportSystemError(err, "%s",
288
_("cannot initialize bridge support"));
292
if (!(driverState->iptables = iptablesContextNew())) {
297
if (virNetworkLoadAllConfigs(&driverState->networks,
298
driverState->networkConfigDir,
299
driverState->networkAutostartDir) < 0)
302
networkFindActiveConfigs(driverState);
303
networkReloadIptablesRules(driverState);
304
networkAutostartConfigs(driverState);
306
networkDriverUnlock(driverState);
315
networkDriverUnlock(driverState);
325
* Function to restart the QEmu daemon, it will recheck the configuration
326
* files and update its state and the networking
329
networkReload(void) {
333
networkDriverLock(driverState);
334
virNetworkLoadAllConfigs(&driverState->networks,
335
driverState->networkConfigDir,
336
driverState->networkAutostartDir);
337
networkReloadIptablesRules(driverState);
338
networkAutostartConfigs(driverState);
339
networkDriverUnlock(driverState);
346
* Checks if the QEmu daemon is active, i.e. has an active domain or
349
* Returns 1 if active, 0 otherwise
352
networkActive(void) {
359
networkDriverLock(driverState);
360
for (i = 0 ; i < driverState->networks.count ; i++) {
361
virNetworkObjPtr net = driverState->networks.objs[i];
362
virNetworkObjLock(net);
363
if (virNetworkObjIsActive(net))
365
virNetworkObjUnlock(net);
367
networkDriverUnlock(driverState);
374
* Shutdown the QEmu daemon, it will stop all active domains and networks
377
networkShutdown(void) {
381
networkDriverLock(driverState);
383
/* free inactive networks */
384
virNetworkObjListFree(&driverState->networks);
386
VIR_FREE(driverState->logDir);
387
VIR_FREE(driverState->networkConfigDir);
388
VIR_FREE(driverState->networkAutostartDir);
390
if (driverState->brctl)
391
brShutdown(driverState->brctl);
392
if (driverState->iptables)
393
iptablesContextFree(driverState->iptables);
395
networkDriverUnlock(driverState);
396
virMutexDestroy(&driverState->lock);
398
VIR_FREE(driverState);
405
networkSaveDnsmasqHostsfile(virNetworkIpDefPtr ipdef,
406
dnsmasqContext *dctx,
411
if (! force && virFileExists(dctx->hostsfile->path))
414
for (i = 0; i < ipdef->nhosts; i++) {
415
virNetworkDHCPHostDefPtr host = &(ipdef->hosts[i]);
416
if ((host->mac) && VIR_SOCKET_HAS_ADDR(&host->ip))
417
dnsmasqAddDhcpHost(dctx, host->mac, &host->ip, host->name);
420
if (dnsmasqSave(dctx) < 0)
428
networkBuildDnsmasqArgv(virNetworkObjPtr network,
429
virNetworkIpDefPtr ipdef,
436
virNetworkIpDefPtr tmpipdef;
438
if (!(bridgeaddr = virSocketFormatAddr(&ipdef->address)))
441
* NB, be careful about syntax for dnsmasq options in long format.
443
* If the flag has a mandatory argument, it can be given using
449
* If the flag has a optional argument, it *must* be given using
454
* It is hard to determine whether a flag is optional or not,
455
* without reading the dnsmasq source :-( The manpage is not
456
* very explicit on this.
460
* Needed to ensure dnsmasq uses same algorithm for processing
461
* multiple namedriver entries in /etc/resolv.conf as GLibC.
463
virCommandAddArgList(cmd, "--strict-order", "--bind-interfaces", NULL);
465
if (network->def->domain)
466
virCommandAddArgList(cmd, "--domain", network->def->domain, NULL);
468
virCommandAddArgPair(cmd, "--pid-file", pidfile);
471
virCommandAddArgList(cmd, "--conf-file=", "", NULL);
473
virCommandAddArgList(cmd,
474
"--except-interface", "lo",
478
* --interface does not actually work with dnsmasq < 2.47,
479
* due to DAD for ipv6 addresses on the interface.
481
* virCommandAddArgList(cmd, "--interface", ipdef->bridge, NULL);
483
* So listen on all defined IPv[46] addresses
486
(tmpipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, ii));
488
char *ipaddr = virSocketFormatAddr(&tmpipdef->address);
491
virCommandAddArgList(cmd, "--listen-address", ipaddr, NULL);
495
for (r = 0 ; r < ipdef->nranges ; r++) {
496
char *saddr = virSocketFormatAddr(&ipdef->ranges[r].start);
499
char *eaddr = virSocketFormatAddr(&ipdef->ranges[r].end);
504
virCommandAddArg(cmd, "--dhcp-range");
505
virCommandAddArgFormat(cmd, "%s,%s", saddr, eaddr);
508
nbleases += virSocketGetRange(&ipdef->ranges[r].start,
509
&ipdef->ranges[r].end);
513
* For static-only DHCP, i.e. with no range but at least one host element,
514
* we have to add a special --dhcp-range option to enable the service in
517
if (!ipdef->nranges && ipdef->nhosts) {
518
virCommandAddArg(cmd, "--dhcp-range");
519
virCommandAddArgFormat(cmd, "%s,static", bridgeaddr);
522
if (ipdef->nranges > 0) {
523
virCommandAddArgFormat(cmd, "--dhcp-lease-max=%d", nbleases);
526
if (ipdef->nranges || ipdef->nhosts)
527
virCommandAddArg(cmd, "--dhcp-no-override");
529
if (ipdef->nhosts > 0) {
530
dnsmasqContext *dctx = dnsmasqContextNew(network->def->name,
537
if (networkSaveDnsmasqHostsfile(ipdef, dctx, false) == 0) {
538
virCommandAddArgPair(cmd, "--dhcp-hostsfile",
539
dctx->hostsfile->path);
541
dnsmasqContextFree(dctx);
544
if (ipdef->tftproot) {
545
virCommandAddArgList(cmd, "--enable-tftp",
546
"--tftp-root", ipdef->tftproot,
549
if (ipdef->bootfile) {
550
virCommandAddArg(cmd, "--dhcp-boot");
551
if (VIR_SOCKET_HAS_ADDR(&ipdef->bootserver)) {
552
char *bootserver = virSocketFormatAddr(&ipdef->bootserver);
556
virCommandAddArgFormat(cmd, "%s%s%s",
557
ipdef->bootfile, ",,", bootserver);
558
VIR_FREE(bootserver);
560
virCommandAddArg(cmd, ipdef->bootfile);
566
VIR_FREE(bridgeaddr);
571
networkStartDhcpDaemon(virNetworkObjPtr network)
573
virCommandPtr cmd = NULL;
574
char *pidfile = NULL;
575
int ret = -1, err, ii;
576
virNetworkIpDefPtr ipdef;
578
network->dnsmasqPid = -1;
580
/* Look for first IPv4 address that has dhcp defined. */
581
/* We support dhcp config on 1 IPv4 interface only. */
583
(ipdef = virNetworkDefGetIpByIndex(network->def, AF_INET, ii));
585
if (ipdef->nranges || ipdef->nhosts)
591
if ((err = virFileMakePath(NETWORK_PID_DIR)) != 0) {
592
virReportSystemError(err,
593
_("cannot create directory %s"),
597
if ((err = virFileMakePath(NETWORK_STATE_DIR)) != 0) {
598
virReportSystemError(err,
599
_("cannot create directory %s"),
604
if (!(pidfile = virFilePid(NETWORK_PID_DIR, network->def->name))) {
609
cmd = virCommandNew(DNSMASQ);
610
if (networkBuildDnsmasqArgv(network, ipdef, pidfile, cmd) < 0) {
614
if (virCommandRun(cmd, NULL) < 0)
618
* There really is no race here - when dnsmasq daemonizes, its
619
* leader process stays around until its child has actually
620
* written its pidfile. So by time virCommandRun exits it has
621
* waitpid'd and guaranteed the proess has started and written a
625
if (virFileReadPid(NETWORK_PID_DIR, network->def->name,
626
&network->dnsmasqPid) < 0)
637
networkStartRadvd(virNetworkObjPtr network)
639
char *pidfile = NULL;
640
char *radvdpidbase = NULL;
641
virBuffer configbuf = VIR_BUFFER_INITIALIZER;;
642
char *configstr = NULL;
643
char *configfile = NULL;
644
virCommandPtr cmd = NULL;
645
int ret = -1, err, ii;
646
virNetworkIpDefPtr ipdef;
648
network->radvdPid = -1;
650
if ((err = virFileMakePath(NETWORK_PID_DIR)) != 0) {
651
virReportSystemError(err,
652
_("cannot create directory %s"),
656
if ((err = virFileMakePath(RADVD_STATE_DIR)) != 0) {
657
virReportSystemError(err,
658
_("cannot create directory %s"),
663
/* construct pidfile name */
664
if (!(radvdpidbase = networkRadvdPidfileBasename(network->def->name))) {
668
if (!(pidfile = virFilePid(NETWORK_PID_DIR, radvdpidbase))) {
673
/* create radvd config file appropriate for this network */
674
virBufferVSprintf(&configbuf, "interface %s\n"
676
" AdvSendAdvert on;\n"
677
" AdvManagedFlag off;\n"
678
" AdvOtherConfigFlag off;\n"
680
network->def->bridge);
682
(ipdef = virNetworkDefGetIpByIndex(network->def, AF_INET6, ii));
687
prefix = virNetworkIpDefPrefix(ipdef);
689
networkReportError(VIR_ERR_INTERNAL_ERROR,
690
_("bridge '%s' has an invalid prefix"),
691
network->def->bridge);
694
if (!(netaddr = virSocketFormatAddr(&ipdef->address)))
696
virBufferVSprintf(&configbuf,
700
" AdvAutonomous on;\n"
701
" AdvRouterAddr off;\n"
707
virBufferAddLit(&configbuf, "};\n");
709
if (virBufferError(&configbuf)) {
713
if (!(configstr = virBufferContentAndReset(&configbuf))) {
718
/* construct the filename */
719
if (!(configfile = networkRadvdConfigFileName(network->def->name))) {
724
if (virFileWriteStr(configfile, configstr, 0600) < 0) {
725
virReportSystemError(errno,
726
_("couldn't write radvd config file '%s'"),
731
/* prevent radvd from daemonizing itself with "--debug 1", and use
732
* a dummy pidfile name - virCommand will create the pidfile we
733
* want to use (this is necessary because radvd's internal
734
* daemonization and pidfile creation causes a race, and the
735
* virFileReadPid() below will fail if we use them).
736
* Unfortunately, it isn't possible to tell radvd to not create
737
* its own pidfile, so we just let it do so, with a slightly
738
* different name. Unused, but harmless.
740
cmd = virCommandNewArgList(RADVD, "--debug", "1",
741
"--config", configfile,
743
virCommandAddArgFormat(cmd, "%s-bin", pidfile);
745
virCommandSetPidFile(cmd, pidfile);
746
virCommandDaemonize(cmd);
748
if (virCommandRun(cmd, NULL) < 0)
751
if (virFileReadPid(NETWORK_PID_DIR, radvdpidbase,
752
&network->radvdPid) < 0)
758
VIR_FREE(configfile);
760
virBufferFreeAndReset(&configbuf);
761
VIR_FREE(radvdpidbase);
767
networkAddMasqueradingIptablesRules(struct network_driver *driver,
768
virNetworkObjPtr network,
769
virNetworkIpDefPtr ipdef)
771
int prefix = virNetworkIpDefPrefix(ipdef);
774
networkReportError(VIR_ERR_INTERNAL_ERROR,
775
_("Invalid prefix or netmask for '%s'"),
776
network->def->bridge);
780
/* allow forwarding packets from the bridge interface */
781
if (iptablesAddForwardAllowOut(driver->iptables,
784
network->def->bridge,
785
network->def->forwardDev) < 0) {
786
networkReportError(VIR_ERR_SYSTEM_ERROR,
787
_("failed to add iptables rule to allow forwarding from '%s'"),
788
network->def->bridge);
792
/* allow forwarding packets to the bridge interface if they are
793
* part of an existing connection
795
if (iptablesAddForwardAllowRelatedIn(driver->iptables,
798
network->def->bridge,
799
network->def->forwardDev) < 0) {
800
networkReportError(VIR_ERR_SYSTEM_ERROR,
801
_("failed to add iptables rule to allow forwarding to '%s'"),
802
network->def->bridge);
807
* Enable masquerading.
809
* We need to end up with 3 rules in the table in this order
811
* 1. protocol=tcp with sport mapping restriction
812
* 2. protocol=udp with sport mapping restriction
813
* 3. generic any protocol
815
* The sport mappings are required, because default IPtables
816
* MASQUERADE maintain port numbers unchanged where possible.
818
* NFS can be configured to only "trust" port numbers < 1023.
820
* Guests using NAT thus need to be prevented from having port
821
* numbers < 1023, otherwise they can bypass the NFS "security"
822
* check on the source port number.
824
* Since we use '--insert' to add rules to the header of the
825
* chain, we actually need to add them in the reverse of the
826
* order just mentioned !
829
/* First the generic masquerade rule for other protocols */
830
if (iptablesAddForwardMasquerade(driver->iptables,
833
network->def->forwardDev,
835
networkReportError(VIR_ERR_SYSTEM_ERROR,
836
_("failed to add iptables rule to enable masquerading to '%s'"),
837
network->def->forwardDev ? network->def->forwardDev : NULL);
841
/* UDP with a source port restriction */
842
if (iptablesAddForwardMasquerade(driver->iptables,
845
network->def->forwardDev,
847
networkReportError(VIR_ERR_SYSTEM_ERROR,
848
_("failed to add iptables rule to enable UDP masquerading to '%s'"),
849
network->def->forwardDev ? network->def->forwardDev : NULL);
853
/* TCP with a source port restriction */
854
if (iptablesAddForwardMasquerade(driver->iptables,
857
network->def->forwardDev,
859
networkReportError(VIR_ERR_SYSTEM_ERROR,
860
_("failed to add iptables rule to enable TCP masquerading to '%s'"),
861
network->def->forwardDev ? network->def->forwardDev : NULL);
868
iptablesRemoveForwardMasquerade(driver->iptables,
871
network->def->forwardDev,
874
iptablesRemoveForwardMasquerade(driver->iptables,
877
network->def->forwardDev,
880
iptablesRemoveForwardAllowRelatedIn(driver->iptables,
883
network->def->bridge,
884
network->def->forwardDev);
886
iptablesRemoveForwardAllowOut(driver->iptables,
889
network->def->bridge,
890
network->def->forwardDev);
896
networkRemoveMasqueradingIptablesRules(struct network_driver *driver,
897
virNetworkObjPtr network,
898
virNetworkIpDefPtr ipdef)
900
int prefix = virNetworkIpDefPrefix(ipdef);
903
iptablesRemoveForwardMasquerade(driver->iptables,
906
network->def->forwardDev,
908
iptablesRemoveForwardMasquerade(driver->iptables,
911
network->def->forwardDev,
913
iptablesRemoveForwardMasquerade(driver->iptables,
916
network->def->forwardDev,
919
iptablesRemoveForwardAllowRelatedIn(driver->iptables,
922
network->def->bridge,
923
network->def->forwardDev);
924
iptablesRemoveForwardAllowOut(driver->iptables,
927
network->def->bridge,
928
network->def->forwardDev);
933
networkAddRoutingIptablesRules(struct network_driver *driver,
934
virNetworkObjPtr network,
935
virNetworkIpDefPtr ipdef)
937
int prefix = virNetworkIpDefPrefix(ipdef);
940
networkReportError(VIR_ERR_INTERNAL_ERROR,
941
_("Invalid prefix or netmask for '%s'"),
942
network->def->bridge);
946
/* allow routing packets from the bridge interface */
947
if (iptablesAddForwardAllowOut(driver->iptables,
950
network->def->bridge,
951
network->def->forwardDev) < 0) {
952
networkReportError(VIR_ERR_SYSTEM_ERROR,
953
_("failed to add iptables rule to allow routing from '%s'"),
954
network->def->bridge);
958
/* allow routing packets to the bridge interface */
959
if (iptablesAddForwardAllowIn(driver->iptables,
962
network->def->bridge,
963
network->def->forwardDev) < 0) {
964
networkReportError(VIR_ERR_SYSTEM_ERROR,
965
_("failed to add iptables rule to allow routing to '%s'"),
966
network->def->bridge);
973
iptablesRemoveForwardAllowOut(driver->iptables,
976
network->def->bridge,
977
network->def->forwardDev);
983
networkRemoveRoutingIptablesRules(struct network_driver *driver,
984
virNetworkObjPtr network,
985
virNetworkIpDefPtr ipdef)
987
int prefix = virNetworkIpDefPrefix(ipdef);
990
iptablesRemoveForwardAllowIn(driver->iptables,
993
network->def->bridge,
994
network->def->forwardDev);
996
iptablesRemoveForwardAllowOut(driver->iptables,
999
network->def->bridge,
1000
network->def->forwardDev);
1004
/* Add all once/network rules required for IPv6 (if any IPv6 addresses are defined) */
1006
networkAddGeneralIp6tablesRules(struct network_driver *driver,
1007
virNetworkObjPtr network)
1010
if (!virNetworkDefGetIpByIndex(network->def, AF_INET6, 0))
1013
/* Catch all rules to block forwarding to/from bridges */
1015
if (iptablesAddForwardRejectOut(driver->iptables, AF_INET6,
1016
network->def->bridge) < 0) {
1017
networkReportError(VIR_ERR_SYSTEM_ERROR,
1018
_("failed to add ip6tables rule to block outbound traffic from '%s'"),
1019
network->def->bridge);
1023
if (iptablesAddForwardRejectIn(driver->iptables, AF_INET6,
1024
network->def->bridge) < 0) {
1025
networkReportError(VIR_ERR_SYSTEM_ERROR,
1026
_("failed to add ip6tables rule to block inbound traffic to '%s'"),
1027
network->def->bridge);
1031
/* Allow traffic between guests on the same bridge */
1032
if (iptablesAddForwardAllowCross(driver->iptables, AF_INET6,
1033
network->def->bridge) < 0) {
1034
networkReportError(VIR_ERR_SYSTEM_ERROR,
1035
_("failed to add ip6tables rule to allow cross bridge traffic on '%s'"),
1036
network->def->bridge);
1040
/* allow DNS over IPv6 */
1041
if (iptablesAddTcpInput(driver->iptables, AF_INET6,
1042
network->def->bridge, 53) < 0) {
1043
networkReportError(VIR_ERR_SYSTEM_ERROR,
1044
_("failed to add ip6tables rule to allow DNS requests from '%s'"),
1045
network->def->bridge);
1049
if (iptablesAddUdpInput(driver->iptables, AF_INET6,
1050
network->def->bridge, 53) < 0) {
1051
networkReportError(VIR_ERR_SYSTEM_ERROR,
1052
_("failed to add ip6tables rule to allow DNS requests from '%s'"),
1053
network->def->bridge);
1059
/* unwind in reverse order from the point of failure */
1061
iptablesRemoveTcpInput(driver->iptables, AF_INET6, network->def->bridge, 53);
1063
iptablesRemoveForwardAllowCross(driver->iptables, AF_INET6, network->def->bridge);
1065
iptablesRemoveForwardRejectIn(driver->iptables, AF_INET6, network->def->bridge);
1067
iptablesRemoveForwardRejectOut(driver->iptables, AF_INET6, network->def->bridge);
1073
networkRemoveGeneralIp6tablesRules(struct network_driver *driver,
1074
virNetworkObjPtr network)
1076
if (!virNetworkDefGetIpByIndex(network->def, AF_INET6, 0))
1079
iptablesRemoveForwardAllowCross(driver->iptables, AF_INET6, network->def->bridge);
1080
iptablesRemoveForwardRejectIn(driver->iptables, AF_INET6, network->def->bridge);
1081
iptablesRemoveForwardRejectOut(driver->iptables, AF_INET6, network->def->bridge);
1085
networkAddGeneralIptablesRules(struct network_driver *driver,
1086
virNetworkObjPtr network)
1089
virNetworkIpDefPtr ipv4def;
1091
/* First look for first IPv4 address that has dhcp or tftpboot defined. */
1092
/* We support dhcp config on 1 IPv4 interface only. */
1094
(ipv4def = virNetworkDefGetIpByIndex(network->def, AF_INET, ii));
1096
if (ipv4def->nranges || ipv4def->nhosts || ipv4def->tftproot)
1100
/* allow DHCP requests through to dnsmasq */
1102
if (iptablesAddTcpInput(driver->iptables, AF_INET,
1103
network->def->bridge, 67) < 0) {
1104
networkReportError(VIR_ERR_SYSTEM_ERROR,
1105
_("failed to add iptables rule to allow DHCP requests from '%s'"),
1106
network->def->bridge);
1110
if (iptablesAddUdpInput(driver->iptables, AF_INET,
1111
network->def->bridge, 67) < 0) {
1112
networkReportError(VIR_ERR_SYSTEM_ERROR,
1113
_("failed to add iptables rule to allow DHCP requests from '%s'"),
1114
network->def->bridge);
1118
/* If we are doing local DHCP service on this network, attempt to
1119
* add a rule that will fixup the checksum of DHCP response
1120
* packets back to the guests (but report failure without
1121
* aborting, since not all iptables implementations support it).
1124
if (ipv4def && (ipv4def->nranges || ipv4def->nhosts) &&
1125
(iptablesAddOutputFixUdpChecksum(driver->iptables,
1126
network->def->bridge, 68) < 0)) {
1127
VIR_WARN("Could not add rule to fixup DHCP response checksums "
1128
"on network '%s'.", network->def->name);
1129
VIR_WARN0("May need to update iptables package & kernel to support CHECKSUM rule.");
1132
/* allow DNS requests through to dnsmasq */
1133
if (iptablesAddTcpInput(driver->iptables, AF_INET,
1134
network->def->bridge, 53) < 0) {
1135
networkReportError(VIR_ERR_SYSTEM_ERROR,
1136
_("failed to add iptables rule to allow DNS requests from '%s'"),
1137
network->def->bridge);
1141
if (iptablesAddUdpInput(driver->iptables, AF_INET,
1142
network->def->bridge, 53) < 0) {
1143
networkReportError(VIR_ERR_SYSTEM_ERROR,
1144
_("failed to add iptables rule to allow DNS requests from '%s'"),
1145
network->def->bridge);
1149
/* allow TFTP requests through to dnsmasq if necessary */
1150
if (ipv4def && ipv4def->tftproot &&
1151
iptablesAddUdpInput(driver->iptables, AF_INET,
1152
network->def->bridge, 69) < 0) {
1153
networkReportError(VIR_ERR_SYSTEM_ERROR,
1154
_("failed to add iptables rule to allow TFTP requests from '%s'"),
1155
network->def->bridge);
1159
/* Catch all rules to block forwarding to/from bridges */
1161
if (iptablesAddForwardRejectOut(driver->iptables, AF_INET,
1162
network->def->bridge) < 0) {
1163
networkReportError(VIR_ERR_SYSTEM_ERROR,
1164
_("failed to add iptables rule to block outbound traffic from '%s'"),
1165
network->def->bridge);
1169
if (iptablesAddForwardRejectIn(driver->iptables, AF_INET,
1170
network->def->bridge) < 0) {
1171
networkReportError(VIR_ERR_SYSTEM_ERROR,
1172
_("failed to add iptables rule to block inbound traffic to '%s'"),
1173
network->def->bridge);
1177
/* Allow traffic between guests on the same bridge */
1178
if (iptablesAddForwardAllowCross(driver->iptables, AF_INET,
1179
network->def->bridge) < 0) {
1180
networkReportError(VIR_ERR_SYSTEM_ERROR,
1181
_("failed to add iptables rule to allow cross bridge traffic on '%s'"),
1182
network->def->bridge);
1186
/* add IPv6 general rules, if needed */
1187
if (networkAddGeneralIp6tablesRules(driver, network) < 0) {
1193
/* unwind in reverse order from the point of failure */
1195
iptablesRemoveForwardAllowCross(driver->iptables, AF_INET, network->def->bridge);
1197
iptablesRemoveForwardRejectIn(driver->iptables, AF_INET, network->def->bridge);
1199
iptablesRemoveForwardRejectOut(driver->iptables, AF_INET, network->def->bridge);
1201
if (ipv4def && ipv4def->tftproot) {
1202
iptablesRemoveUdpInput(driver->iptables, AF_INET, network->def->bridge, 69);
1205
iptablesRemoveUdpInput(driver->iptables, AF_INET, network->def->bridge, 53);
1207
iptablesRemoveTcpInput(driver->iptables, AF_INET, network->def->bridge, 53);
1209
iptablesRemoveUdpInput(driver->iptables, AF_INET, network->def->bridge, 67);
1211
iptablesRemoveTcpInput(driver->iptables, AF_INET, network->def->bridge, 67);
1217
networkRemoveGeneralIptablesRules(struct network_driver *driver,
1218
virNetworkObjPtr network)
1221
virNetworkIpDefPtr ipv4def;
1223
networkRemoveGeneralIp6tablesRules(driver, network);
1226
(ipv4def = virNetworkDefGetIpByIndex(network->def, AF_INET, ii));
1228
if (ipv4def->nranges || ipv4def->nhosts || ipv4def->tftproot)
1232
iptablesRemoveForwardAllowCross(driver->iptables, AF_INET, network->def->bridge);
1233
iptablesRemoveForwardRejectIn(driver->iptables, AF_INET, network->def->bridge);
1234
iptablesRemoveForwardRejectOut(driver->iptables, AF_INET, network->def->bridge);
1235
if (ipv4def && ipv4def->tftproot) {
1236
iptablesRemoveUdpInput(driver->iptables, AF_INET, network->def->bridge, 69);
1238
iptablesRemoveUdpInput(driver->iptables, AF_INET, network->def->bridge, 53);
1239
iptablesRemoveTcpInput(driver->iptables, AF_INET, network->def->bridge, 53);
1240
if (ipv4def && (ipv4def->nranges || ipv4def->nhosts)) {
1241
iptablesRemoveOutputFixUdpChecksum(driver->iptables,
1242
network->def->bridge, 68);
1244
iptablesRemoveUdpInput(driver->iptables, AF_INET, network->def->bridge, 67);
1245
iptablesRemoveTcpInput(driver->iptables, AF_INET, network->def->bridge, 67);
1249
networkAddIpSpecificIptablesRules(struct network_driver *driver,
1250
virNetworkObjPtr network,
1251
virNetworkIpDefPtr ipdef)
1253
/* NB: in the case of IPv6, routing rules are added when the
1254
* forward mode is NAT. This is because IPv6 has no NAT.
1257
if (network->def->forwardType == VIR_NETWORK_FORWARD_NAT) {
1258
if (VIR_SOCKET_IS_FAMILY(&ipdef->address, AF_INET))
1259
return networkAddMasqueradingIptablesRules(driver, network, ipdef);
1260
else if (VIR_SOCKET_IS_FAMILY(&ipdef->address, AF_INET6))
1261
return networkAddRoutingIptablesRules(driver, network, ipdef);
1262
} else if (network->def->forwardType == VIR_NETWORK_FORWARD_ROUTE) {
1263
return networkAddRoutingIptablesRules(driver, network, ipdef);
1269
networkRemoveIpSpecificIptablesRules(struct network_driver *driver,
1270
virNetworkObjPtr network,
1271
virNetworkIpDefPtr ipdef)
1273
if (network->def->forwardType == VIR_NETWORK_FORWARD_NAT) {
1274
if (VIR_SOCKET_IS_FAMILY(&ipdef->address, AF_INET))
1275
networkRemoveMasqueradingIptablesRules(driver, network, ipdef);
1276
else if (VIR_SOCKET_IS_FAMILY(&ipdef->address, AF_INET6))
1277
networkRemoveRoutingIptablesRules(driver, network, ipdef);
1278
} else if (network->def->forwardType == VIR_NETWORK_FORWARD_ROUTE) {
1279
networkRemoveRoutingIptablesRules(driver, network, ipdef);
1283
/* Add all rules for all ip addresses (and general rules) on a network */
1285
networkAddIptablesRules(struct network_driver *driver,
1286
virNetworkObjPtr network)
1289
virNetworkIpDefPtr ipdef;
1291
/* Add "once per network" rules */
1292
if (networkAddGeneralIptablesRules(driver, network) < 0)
1296
(ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, ii));
1298
/* Add address-specific iptables rules */
1299
if (networkAddIpSpecificIptablesRules(driver, network, ipdef) < 0) {
1306
/* The final failed call to networkAddIpSpecificIptablesRules will
1307
* have removed any rules it created, but we need to remove those
1308
* added for previous IP addresses.
1310
while ((--ii >= 0) &&
1311
(ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, ii))) {
1312
networkRemoveIpSpecificIptablesRules(driver, network, ipdef);
1314
networkRemoveGeneralIptablesRules(driver, network);
1318
/* Remove all rules for all ip addresses (and general rules) on a network */
1320
networkRemoveIptablesRules(struct network_driver *driver,
1321
virNetworkObjPtr network)
1324
virNetworkIpDefPtr ipdef;
1327
(ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, ii));
1329
networkRemoveIpSpecificIptablesRules(driver, network, ipdef);
1331
networkRemoveGeneralIptablesRules(driver, network);
1335
networkReloadIptablesRules(struct network_driver *driver)
1339
VIR_INFO0(_("Reloading iptables rules"));
1341
for (i = 0 ; i < driver->networks.count ; i++) {
1342
virNetworkObjLock(driver->networks.objs[i]);
1343
if (virNetworkObjIsActive(driver->networks.objs[i])) {
1344
networkRemoveIptablesRules(driver, driver->networks.objs[i]);
1345
if (networkAddIptablesRules(driver, driver->networks.objs[i]) < 0) {
1346
/* failed to add but already logged */
1349
virNetworkObjUnlock(driver->networks.objs[i]);
1353
/* Enable IP Forwarding. Return 0 for success, -1 for failure. */
1355
networkEnableIpForwarding(bool enableIPv4, bool enableIPv6)
1359
ret = virFileWriteStr("/proc/sys/net/ipv4/ip_forward", "1\n", 0);
1360
if (enableIPv6 && ret == 0)
1361
ret = virFileWriteStr("/proc/sys/net/ipv6/conf/all/forwarding", "1\n", 0);
1365
#define SYSCTL_PATH "/proc/sys"
1368
networkSetIPv6Sysctls(virNetworkObjPtr network)
1373
if (!virNetworkDefGetIpByIndex(network->def, AF_INET6, 0)) {
1374
/* Only set disable_ipv6 if there are no ipv6 addresses defined for
1377
if (virAsprintf(&field, SYSCTL_PATH "/net/ipv6/conf/%s/disable_ipv6",
1378
network->def->bridge) < 0) {
1379
virReportOOMError();
1383
if (access(field, W_OK) < 0 && errno == ENOENT) {
1384
VIR_DEBUG("ipv6 appears to already be disabled on %s",
1385
network->def->bridge);
1390
if (virFileWriteStr(field, "1", 0) < 0) {
1391
virReportSystemError(errno,
1392
_("cannot write to %s to disable IPv6 on bridge %s"),
1393
field, network->def->bridge);
1399
/* The rest of the ipv6 sysctl tunables should always be set,
1400
* whether or not we're using ipv6 on this bridge.
1403
/* Prevent guests from hijacking the host network by sending out
1404
* their own router advertisements.
1406
if (virAsprintf(&field, SYSCTL_PATH "/net/ipv6/conf/%s/accept_ra",
1407
network->def->bridge) < 0) {
1408
virReportOOMError();
1412
if (virFileWriteStr(field, "0", 0) < 0) {
1413
virReportSystemError(errno,
1414
_("cannot disable %s"), field);
1419
/* All interfaces used as a gateway (which is what this is, by
1420
* definition), must always have autoconf=0.
1422
if (virAsprintf(&field, SYSCTL_PATH "/net/ipv6/conf/%s/autoconf",
1423
network->def->bridge) < 0) {
1424
virReportOOMError();
1428
if (virFileWriteStr(field, "1", 0) < 0) {
1429
virReportSystemError(errno,
1430
_("cannot enable %s"), field);
1440
#define PROC_NET_ROUTE "/proc/net/route"
1442
/* XXX: This function can be a lot more exhaustive, there are certainly
1443
* other scenarios where we can ruin host network connectivity.
1444
* XXX: Using a proper library is preferred over parsing /proc
1447
networkCheckRouteCollision(virNetworkObjPtr network)
1450
char *cur, *buf = NULL;
1451
enum {MAX_ROUTE_SIZE = 1024*64};
1453
/* Read whole routing table into memory */
1454
if ((len = virFileReadAll(PROC_NET_ROUTE, MAX_ROUTE_SIZE, &buf)) < 0)
1457
/* Dropping the last character shouldn't hurt */
1461
VIR_DEBUG("%s output:\n%s", PROC_NET_ROUTE, buf);
1463
if (!STRPREFIX (buf, "Iface"))
1466
/* First line is just headings, skip it */
1467
cur = strchr(buf, '\n');
1472
char iface[17], dest[128], mask[128];
1473
unsigned int addr_val, mask_val;
1474
virNetworkIpDefPtr ipdef;
1477
/* NUL-terminate the line, so sscanf doesn't go beyond a newline. */
1478
char *nl = strchr(cur, '\n');
1483
num = sscanf(cur, "%16s %127s %*s %*s %*s %*s %*s %127s",
1488
VIR_DEBUG("Failed to parse %s", PROC_NET_ROUTE);
1492
if (virStrToLong_ui(dest, NULL, 16, &addr_val) < 0) {
1493
VIR_DEBUG("Failed to convert network address %s to uint", dest);
1497
if (virStrToLong_ui(mask, NULL, 16, &mask_val) < 0) {
1498
VIR_DEBUG("Failed to convert network mask %s to uint", mask);
1502
addr_val &= mask_val;
1505
(ipdef = virNetworkDefGetIpByIndex(network->def, AF_INET, ii));
1508
unsigned int net_dest;
1509
virSocketAddr netmask;
1511
if (virNetworkIpDefNetmask(ipdef, &netmask) < 0) {
1512
VIR_WARN("Failed to get netmask of '%s'",
1513
network->def->bridge);
1517
net_dest = (ipdef->address.data.inet4.sin_addr.s_addr &
1518
netmask.data.inet4.sin_addr.s_addr);
1520
if ((net_dest == addr_val) &&
1521
(netmask.data.inet4.sin_addr.s_addr == mask_val)) {
1522
networkReportError(VIR_ERR_INTERNAL_ERROR,
1523
_("Network is already in use by interface %s"),
1537
networkAddAddrToBridge(struct network_driver *driver,
1538
virNetworkObjPtr network,
1539
virNetworkIpDefPtr ipdef)
1541
int prefix = virNetworkIpDefPrefix(ipdef);
1544
networkReportError(VIR_ERR_INTERNAL_ERROR,
1545
_("bridge '%s' has an invalid netmask or IP address"),
1546
network->def->bridge);
1550
if (brAddInetAddress(driver->brctl, network->def->bridge,
1551
&ipdef->address, prefix) < 0) {
1552
networkReportError(VIR_ERR_INTERNAL_ERROR,
1553
_("cannot set IP address on bridge '%s'"),
1554
network->def->bridge);
1562
networkStartNetworkDaemon(struct network_driver *driver,
1563
virNetworkObjPtr network)
1566
bool v4present = false, v6present = false;
1567
virErrorPtr save_err = NULL;
1568
virNetworkIpDefPtr ipdef;
1570
if (virNetworkObjIsActive(network)) {
1571
networkReportError(VIR_ERR_OPERATION_INVALID,
1572
"%s", _("network is already active"));
1576
/* Check to see if any network IP collides with an existing route */
1577
if (networkCheckRouteCollision(network) < 0)
1580
/* Create and configure the bridge device */
1581
if ((err = brAddBridge(driver->brctl, network->def->bridge))) {
1582
virReportSystemError(err,
1583
_("cannot create bridge '%s'"),
1584
network->def->bridge);
1588
/* Set bridge options */
1589
if (brSetForwardDelay(driver->brctl, network->def->bridge,
1590
network->def->delay)) {
1591
networkReportError(VIR_ERR_INTERNAL_ERROR,
1592
_("cannot set forward delay on bridge '%s'"),
1593
network->def->bridge);
1597
if (brSetEnableSTP(driver->brctl, network->def->bridge,
1598
network->def->stp ? 1 : 0)) {
1599
networkReportError(VIR_ERR_INTERNAL_ERROR,
1600
_("cannot set STP '%s' on bridge '%s'"),
1601
network->def->stp ? "on" : "off", network->def->bridge);
1605
/* Disable IPv6 on the bridge if there are no IPv6 addresses
1606
* defined, and set other IPv6 sysctl tunables appropriately.
1608
if (networkSetIPv6Sysctls(network) < 0)
1611
/* Add "once per network" rules */
1612
if (networkAddIptablesRules(driver, network) < 0)
1616
(ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, ii));
1618
if (VIR_SOCKET_IS_FAMILY(&ipdef->address, AF_INET))
1620
if (VIR_SOCKET_IS_FAMILY(&ipdef->address, AF_INET6))
1623
/* Add the IP address/netmask to the bridge */
1624
if (networkAddAddrToBridge(driver, network, ipdef) < 0) {
1629
/* Bring up the bridge interface */
1630
if ((err = brSetInterfaceUp(driver->brctl, network->def->bridge, 1))) {
1631
virReportSystemError(err,
1632
_("failed to bring the bridge '%s' up"),
1633
network->def->bridge);
1637
/* If forwardType != NONE, turn on global IP forwarding */
1638
if (network->def->forwardType != VIR_NETWORK_FORWARD_NONE &&
1639
networkEnableIpForwarding(v4present, v6present) < 0) {
1640
virReportSystemError(errno, "%s",
1641
_("failed to enable IP forwarding"));
1646
/* start dnsmasq if there are any IPv4 addresses */
1647
if (v4present && networkStartDhcpDaemon(network) < 0)
1650
/* start radvd if there are any ipv6 addresses */
1651
if (v6present && networkStartRadvd(network) < 0)
1654
/* Persist the live configuration now we have bridge info */
1655
if (virNetworkSaveConfig(NETWORK_STATE_DIR, network->def) < 0) {
1659
network->active = 1;
1665
save_err = virSaveLastError();
1667
if (network->radvdPid > 0) {
1668
kill(network->radvdPid, SIGTERM);
1669
network->radvdPid = -1;
1674
save_err = virSaveLastError();
1676
if (network->dnsmasqPid > 0) {
1677
kill(network->dnsmasqPid, SIGTERM);
1678
network->dnsmasqPid = -1;
1683
save_err = virSaveLastError();
1684
if ((err = brSetInterfaceUp(driver->brctl, network->def->bridge, 0))) {
1686
VIR_WARN("Failed to bring down bridge '%s' : %s",
1687
network->def->bridge, virStrerror(err, ebuf, sizeof ebuf));
1692
save_err = virSaveLastError();
1693
networkRemoveIptablesRules(driver, network);
1697
save_err = virSaveLastError();
1698
if ((err = brDeleteBridge(driver->brctl, network->def->bridge))) {
1700
VIR_WARN("Failed to delete bridge '%s' : %s",
1701
network->def->bridge, virStrerror(err, ebuf, sizeof ebuf));
1705
virSetError(save_err);
1706
virFreeError(save_err);
1712
static int networkShutdownNetworkDaemon(struct network_driver *driver,
1713
virNetworkObjPtr network)
1718
VIR_INFO(_("Shutting down network '%s'"), network->def->name);
1720
if (!virNetworkObjIsActive(network))
1723
stateFile = virNetworkConfigFile(NETWORK_STATE_DIR, network->def->name);
1728
VIR_FREE(stateFile);
1730
if (network->radvdPid > 0) {
1733
kill(network->radvdPid, SIGTERM);
1734
/* attempt to delete the pidfile we created */
1735
if (!(radvdpidbase = networkRadvdPidfileBasename(network->def->name))) {
1736
virReportOOMError();
1738
virFileDeletePid(NETWORK_PID_DIR, radvdpidbase);
1739
VIR_FREE(radvdpidbase);
1743
if (network->dnsmasqPid > 0)
1744
kill(network->dnsmasqPid, SIGTERM);
1747
if ((err = brSetInterfaceUp(driver->brctl, network->def->bridge, 0))) {
1748
VIR_WARN("Failed to bring down bridge '%s' : %s",
1749
network->def->bridge, virStrerror(err, ebuf, sizeof ebuf));
1752
networkRemoveIptablesRules(driver, network);
1754
if ((err = brDeleteBridge(driver->brctl, network->def->bridge))) {
1755
VIR_WARN("Failed to delete bridge '%s' : %s",
1756
network->def->bridge, virStrerror(err, ebuf, sizeof ebuf));
1759
/* See if its still alive and really really kill it */
1760
if (network->dnsmasqPid > 0 &&
1761
(kill(network->dnsmasqPid, 0) == 0))
1762
kill(network->dnsmasqPid, SIGKILL);
1763
network->dnsmasqPid = -1;
1765
if (network->radvdPid > 0 &&
1766
(kill(network->radvdPid, 0) == 0))
1767
kill(network->radvdPid, SIGKILL);
1768
network->radvdPid = -1;
1770
network->active = 0;
1772
if (network->newDef) {
1773
virNetworkDefFree(network->def);
1774
network->def = network->newDef;
1775
network->newDef = NULL;
1782
static virNetworkPtr networkLookupByUUID(virConnectPtr conn,
1783
const unsigned char *uuid) {
1784
struct network_driver *driver = conn->networkPrivateData;
1785
virNetworkObjPtr network;
1786
virNetworkPtr ret = NULL;
1788
networkDriverLock(driver);
1789
network = virNetworkFindByUUID(&driver->networks, uuid);
1790
networkDriverUnlock(driver);
1792
networkReportError(VIR_ERR_NO_NETWORK,
1793
"%s", _("no network with matching uuid"));
1797
ret = virGetNetwork(conn, network->def->name, network->def->uuid);
1801
virNetworkObjUnlock(network);
1805
static virNetworkPtr networkLookupByName(virConnectPtr conn,
1807
struct network_driver *driver = conn->networkPrivateData;
1808
virNetworkObjPtr network;
1809
virNetworkPtr ret = NULL;
1811
networkDriverLock(driver);
1812
network = virNetworkFindByName(&driver->networks, name);
1813
networkDriverUnlock(driver);
1815
networkReportError(VIR_ERR_NO_NETWORK,
1816
_("no network with matching name '%s'"), name);
1820
ret = virGetNetwork(conn, network->def->name, network->def->uuid);
1824
virNetworkObjUnlock(network);
1828
static virDrvOpenStatus networkOpenNetwork(virConnectPtr conn,
1829
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
1830
int flags ATTRIBUTE_UNUSED) {
1832
return VIR_DRV_OPEN_DECLINED;
1834
conn->networkPrivateData = driverState;
1835
return VIR_DRV_OPEN_SUCCESS;
1838
static int networkCloseNetwork(virConnectPtr conn) {
1839
conn->networkPrivateData = NULL;
1843
static int networkNumNetworks(virConnectPtr conn) {
1845
struct network_driver *driver = conn->networkPrivateData;
1847
networkDriverLock(driver);
1848
for (i = 0 ; i < driver->networks.count ; i++) {
1849
virNetworkObjLock(driver->networks.objs[i]);
1850
if (virNetworkObjIsActive(driver->networks.objs[i]))
1852
virNetworkObjUnlock(driver->networks.objs[i]);
1854
networkDriverUnlock(driver);
1859
static int networkListNetworks(virConnectPtr conn, char **const names, int nnames) {
1860
struct network_driver *driver = conn->networkPrivateData;
1863
networkDriverLock(driver);
1864
for (i = 0 ; i < driver->networks.count && got < nnames ; i++) {
1865
virNetworkObjLock(driver->networks.objs[i]);
1866
if (virNetworkObjIsActive(driver->networks.objs[i])) {
1867
if (!(names[got] = strdup(driver->networks.objs[i]->def->name))) {
1868
virNetworkObjUnlock(driver->networks.objs[i]);
1869
virReportOOMError();
1874
virNetworkObjUnlock(driver->networks.objs[i]);
1876
networkDriverUnlock(driver);
1881
networkDriverUnlock(driver);
1882
for (i = 0 ; i < got ; i++)
1887
static int networkNumDefinedNetworks(virConnectPtr conn) {
1888
int ninactive = 0, i;
1889
struct network_driver *driver = conn->networkPrivateData;
1891
networkDriverLock(driver);
1892
for (i = 0 ; i < driver->networks.count ; i++) {
1893
virNetworkObjLock(driver->networks.objs[i]);
1894
if (!virNetworkObjIsActive(driver->networks.objs[i]))
1896
virNetworkObjUnlock(driver->networks.objs[i]);
1898
networkDriverUnlock(driver);
1903
static int networkListDefinedNetworks(virConnectPtr conn, char **const names, int nnames) {
1904
struct network_driver *driver = conn->networkPrivateData;
1907
networkDriverLock(driver);
1908
for (i = 0 ; i < driver->networks.count && got < nnames ; i++) {
1909
virNetworkObjLock(driver->networks.objs[i]);
1910
if (!virNetworkObjIsActive(driver->networks.objs[i])) {
1911
if (!(names[got] = strdup(driver->networks.objs[i]->def->name))) {
1912
virNetworkObjUnlock(driver->networks.objs[i]);
1913
virReportOOMError();
1918
virNetworkObjUnlock(driver->networks.objs[i]);
1920
networkDriverUnlock(driver);
1924
networkDriverUnlock(driver);
1925
for (i = 0 ; i < got ; i++)
1931
static int networkIsActive(virNetworkPtr net)
1933
struct network_driver *driver = net->conn->networkPrivateData;
1934
virNetworkObjPtr obj;
1937
networkDriverLock(driver);
1938
obj = virNetworkFindByUUID(&driver->networks, net->uuid);
1939
networkDriverUnlock(driver);
1941
networkReportError(VIR_ERR_NO_NETWORK, NULL);
1944
ret = virNetworkObjIsActive(obj);
1948
virNetworkObjUnlock(obj);
1952
static int networkIsPersistent(virNetworkPtr net)
1954
struct network_driver *driver = net->conn->networkPrivateData;
1955
virNetworkObjPtr obj;
1958
networkDriverLock(driver);
1959
obj = virNetworkFindByUUID(&driver->networks, net->uuid);
1960
networkDriverUnlock(driver);
1962
networkReportError(VIR_ERR_NO_NETWORK, NULL);
1965
ret = obj->persistent;
1969
virNetworkObjUnlock(obj);
1974
static virNetworkPtr networkCreate(virConnectPtr conn, const char *xml) {
1975
struct network_driver *driver = conn->networkPrivateData;
1976
virNetworkDefPtr def;
1977
virNetworkObjPtr network = NULL;
1978
virNetworkPtr ret = NULL;
1980
networkDriverLock(driver);
1982
if (!(def = virNetworkDefParseString(xml)))
1985
if (virNetworkObjIsDuplicate(&driver->networks, def, 1) < 0)
1988
if (virNetworkSetBridgeName(&driver->networks, def, 1))
1991
if (!(network = virNetworkAssignDef(&driver->networks,
1996
if (networkStartNetworkDaemon(driver, network) < 0) {
1997
virNetworkRemoveInactive(&driver->networks,
2003
ret = virGetNetwork(conn, network->def->name, network->def->uuid);
2006
virNetworkDefFree(def);
2008
virNetworkObjUnlock(network);
2009
networkDriverUnlock(driver);
2013
static virNetworkPtr networkDefine(virConnectPtr conn, const char *xml) {
2014
struct network_driver *driver = conn->networkPrivateData;
2015
virNetworkIpDefPtr ipdef, ipv4def = NULL;
2016
virNetworkDefPtr def;
2017
virNetworkObjPtr network = NULL;
2018
virNetworkPtr ret = NULL;
2021
networkDriverLock(driver);
2023
if (!(def = virNetworkDefParseString(xml)))
2026
if (virNetworkObjIsDuplicate(&driver->networks, def, 0) < 0)
2029
if (virNetworkSetBridgeName(&driver->networks, def, 1))
2032
if (!(network = virNetworkAssignDef(&driver->networks,
2037
network->persistent = 1;
2039
if (virNetworkSaveConfig(driver->networkConfigDir,
2040
network->newDef ? network->newDef : network->def) < 0) {
2041
virNetworkRemoveInactive(&driver->networks,
2047
/* We only support dhcp on one IPv4 address per defined network */
2049
(ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, ii));
2051
if (VIR_SOCKET_IS_FAMILY(&ipdef->address, AF_INET)) {
2052
if (ipdef->nranges || ipdef->nhosts) {
2054
networkReportError(VIR_ERR_CONFIG_UNSUPPORTED,
2055
"%s", _("Multiple dhcp sections found. dhcp is supported only for a single IPv4 address on each network"));
2064
dnsmasqContext *dctx = dnsmasqContextNew(network->def->name, DNSMASQ_STATE_DIR);
2068
networkSaveDnsmasqHostsfile(ipv4def, dctx, true);
2069
dnsmasqContextFree(dctx);
2072
ret = virGetNetwork(conn, network->def->name, network->def->uuid);
2075
virNetworkDefFree(def);
2077
virNetworkObjUnlock(network);
2078
networkDriverUnlock(driver);
2082
static int networkUndefine(virNetworkPtr net) {
2083
struct network_driver *driver = net->conn->networkPrivateData;
2084
virNetworkObjPtr network;
2085
virNetworkIpDefPtr ipdef;
2086
bool dhcp_present = false, v6present = false;
2089
networkDriverLock(driver);
2091
network = virNetworkFindByUUID(&driver->networks, net->uuid);
2093
networkReportError(VIR_ERR_NO_NETWORK,
2094
"%s", _("no network with matching uuid"));
2098
if (virNetworkObjIsActive(network)) {
2099
networkReportError(VIR_ERR_OPERATION_INVALID,
2100
"%s", _("network is still active"));
2104
if (virNetworkDeleteConfig(driver->networkConfigDir,
2105
driver->networkAutostartDir,
2109
/* we only support dhcp on one IPv4 address per defined network */
2111
(ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, ii));
2113
if (VIR_SOCKET_IS_FAMILY(&ipdef->address, AF_INET)) {
2114
if (ipdef->nranges || ipdef->nhosts)
2115
dhcp_present = true;
2116
} else if (VIR_SOCKET_IS_FAMILY(&ipdef->address, AF_INET6)) {
2122
dnsmasqContext *dctx = dnsmasqContextNew(network->def->name, DNSMASQ_STATE_DIR);
2126
dnsmasqDelete(dctx);
2127
dnsmasqContextFree(dctx);
2131
char *configfile = networkRadvdConfigFileName(network->def->name);
2134
virReportOOMError();
2138
VIR_FREE(configfile);
2140
char *radvdpidbase = networkRadvdPidfileBasename(network->def->name);
2142
if (!(radvdpidbase)) {
2143
virReportOOMError();
2146
virFileDeletePid(NETWORK_PID_DIR, radvdpidbase);
2147
VIR_FREE(radvdpidbase);
2151
virNetworkRemoveInactive(&driver->networks,
2158
virNetworkObjUnlock(network);
2159
networkDriverUnlock(driver);
2163
static int networkStart(virNetworkPtr net) {
2164
struct network_driver *driver = net->conn->networkPrivateData;
2165
virNetworkObjPtr network;
2168
networkDriverLock(driver);
2169
network = virNetworkFindByUUID(&driver->networks, net->uuid);
2172
networkReportError(VIR_ERR_NO_NETWORK,
2173
"%s", _("no network with matching uuid"));
2177
ret = networkStartNetworkDaemon(driver, network);
2181
virNetworkObjUnlock(network);
2182
networkDriverUnlock(driver);
2186
static int networkDestroy(virNetworkPtr net) {
2187
struct network_driver *driver = net->conn->networkPrivateData;
2188
virNetworkObjPtr network;
2191
networkDriverLock(driver);
2192
network = virNetworkFindByUUID(&driver->networks, net->uuid);
2195
networkReportError(VIR_ERR_NO_NETWORK,
2196
"%s", _("no network with matching uuid"));
2200
if (!virNetworkObjIsActive(network)) {
2201
networkReportError(VIR_ERR_OPERATION_INVALID,
2202
"%s", _("network is not active"));
2206
ret = networkShutdownNetworkDaemon(driver, network);
2207
if (!network->persistent) {
2208
virNetworkRemoveInactive(&driver->networks,
2215
virNetworkObjUnlock(network);
2216
networkDriverUnlock(driver);
2220
static char *networkDumpXML(virNetworkPtr net, int flags ATTRIBUTE_UNUSED) {
2221
struct network_driver *driver = net->conn->networkPrivateData;
2222
virNetworkObjPtr network;
2225
networkDriverLock(driver);
2226
network = virNetworkFindByUUID(&driver->networks, net->uuid);
2227
networkDriverUnlock(driver);
2230
networkReportError(VIR_ERR_NO_NETWORK,
2231
"%s", _("no network with matching uuid"));
2235
ret = virNetworkDefFormat(network->def);
2239
virNetworkObjUnlock(network);
2243
static char *networkGetBridgeName(virNetworkPtr net) {
2244
struct network_driver *driver = net->conn->networkPrivateData;
2245
virNetworkObjPtr network;
2246
char *bridge = NULL;
2248
networkDriverLock(driver);
2249
network = virNetworkFindByUUID(&driver->networks, net->uuid);
2250
networkDriverUnlock(driver);
2253
networkReportError(VIR_ERR_NO_NETWORK,
2254
"%s", _("no network with matching id"));
2258
if (!(network->def->bridge)) {
2259
networkReportError(VIR_ERR_INTERNAL_ERROR,
2260
_("network '%s' does not have a bridge name."),
2261
network->def->name);
2265
bridge = strdup(network->def->bridge);
2267
virReportOOMError();
2271
virNetworkObjUnlock(network);
2275
static int networkGetAutostart(virNetworkPtr net,
2277
struct network_driver *driver = net->conn->networkPrivateData;
2278
virNetworkObjPtr network;
2281
networkDriverLock(driver);
2282
network = virNetworkFindByUUID(&driver->networks, net->uuid);
2283
networkDriverUnlock(driver);
2285
networkReportError(VIR_ERR_NO_NETWORK,
2286
"%s", _("no network with matching uuid"));
2290
*autostart = network->autostart;
2295
virNetworkObjUnlock(network);
2299
static int networkSetAutostart(virNetworkPtr net,
2301
struct network_driver *driver = net->conn->networkPrivateData;
2302
virNetworkObjPtr network;
2303
char *configFile = NULL, *autostartLink = NULL;
2306
networkDriverLock(driver);
2307
network = virNetworkFindByUUID(&driver->networks, net->uuid);
2310
networkReportError(VIR_ERR_NO_NETWORK,
2311
"%s", _("no network with matching uuid"));
2315
if (!network->persistent) {
2316
networkReportError(VIR_ERR_OPERATION_INVALID,
2317
"%s", _("cannot set autostart for transient network"));
2321
autostart = (autostart != 0);
2323
if (network->autostart != autostart) {
2324
if ((configFile = virNetworkConfigFile(driver->networkConfigDir, network->def->name)) == NULL)
2326
if ((autostartLink = virNetworkConfigFile(driver->networkAutostartDir, network->def->name)) == NULL)
2330
if (virFileMakePath(driver->networkAutostartDir)) {
2331
virReportSystemError(errno,
2332
_("cannot create autostart directory '%s'"),
2333
driver->networkAutostartDir);
2337
if (symlink(configFile, autostartLink) < 0) {
2338
virReportSystemError(errno,
2339
_("Failed to create symlink '%s' to '%s'"),
2340
autostartLink, configFile);
2344
if (unlink(autostartLink) < 0 && errno != ENOENT && errno != ENOTDIR) {
2345
virReportSystemError(errno,
2346
_("Failed to delete symlink '%s'"),
2352
network->autostart = autostart;
2357
VIR_FREE(configFile);
2358
VIR_FREE(autostartLink);
2360
virNetworkObjUnlock(network);
2361
networkDriverUnlock(driver);
2366
static virNetworkDriver networkDriver = {
2368
networkOpenNetwork, /* open */
2369
networkCloseNetwork, /* close */
2370
networkNumNetworks, /* numOfNetworks */
2371
networkListNetworks, /* listNetworks */
2372
networkNumDefinedNetworks, /* numOfDefinedNetworks */
2373
networkListDefinedNetworks, /* listDefinedNetworks */
2374
networkLookupByUUID, /* networkLookupByUUID */
2375
networkLookupByName, /* networkLookupByName */
2376
networkCreate, /* networkCreateXML */
2377
networkDefine, /* networkDefineXML */
2378
networkUndefine, /* networkUndefine */
2379
networkStart, /* networkCreate */
2380
networkDestroy, /* networkDestroy */
2381
networkDumpXML, /* networkDumpXML */
2382
networkGetBridgeName, /* networkGetBridgeName */
2383
networkGetAutostart, /* networkGetAutostart */
2384
networkSetAutostart, /* networkSetAutostart */
2386
networkIsPersistent,
2389
static virStateDriver networkStateDriver = {
2397
int networkRegister(void) {
2398
virRegisterNetworkDriver(&networkDriver);
2399
virRegisterStateDriver(&networkStateDriver);