~ubuntu-branches/ubuntu/raring/libvirt/raring

« back to all changes in this revision

Viewing changes to src/network/bridge_driver.c

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2012-11-19 10:41:02 UTC
  • mfrom: (1.2.15) (223.1.2 raring-proposed)
  • Revision ID: package-import@ubuntu.com-20121119104102-l6ewdppikysbzztu
Tags: 1.0.0-0ubuntu2
debian/patches/add-armhf-sysinfo-infomration.patch: Disable
to fix FTBFS on arm.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 * Lesser General Public License for more details.
16
16
 *
17
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
 
18
 * License along with this library.  If not, see
 
19
 * <http://www.gnu.org/licenses/>.
20
20
 *
21
21
 * Author: Daniel P. Berrange <berrange@redhat.com>
22
22
 */
47
47
#include "datatypes.h"
48
48
#include "bridge_driver.h"
49
49
#include "network_conf.h"
 
50
#include "device_conf.h"
50
51
#include "driver.h"
51
52
#include "buf.h"
52
53
#include "virpidfile.h"
59
60
#include "dnsmasq.h"
60
61
#include "configmake.h"
61
62
#include "virnetdev.h"
 
63
#include "pci.h"
62
64
#include "virnetdevbridge.h"
63
65
#include "virnetdevtap.h"
 
66
#include "virnetdevvportprofile.h"
 
67
#include "virdbus.h"
 
68
#include "virfile.h"
64
69
 
65
70
#define NETWORK_PID_DIR LOCALSTATEDIR "/run/libvirt/network"
66
71
#define NETWORK_STATE_DIR LOCALSTATEDIR "/lib/libvirt/network"
70
75
 
71
76
#define VIR_FROM_THIS VIR_FROM_NETWORK
72
77
 
73
 
#define networkReportError(code, ...)                                   \
74
 
    virReportErrorHelper(VIR_FROM_NETWORK, code, __FILE__,              \
75
 
                         __FUNCTION__, __LINE__, __VA_ARGS__)
76
 
 
77
78
/* Main driver state */
78
79
struct network_driver {
79
80
    virMutex lock;
117
118
                                        virNetworkObjPtr network);
118
119
 
119
120
static void networkReloadIptablesRules(struct network_driver *driver);
 
121
static void networkRefreshDaemons(struct network_driver *driver);
120
122
 
121
123
static struct network_driver *driverState = NULL;
122
124
 
252
254
    }
253
255
}
254
256
 
 
257
#if HAVE_FIREWALLD
 
258
static DBusHandlerResult
 
259
firewalld_dbus_filter_bridge(DBusConnection *connection ATTRIBUTE_UNUSED,
 
260
                             DBusMessage *message, void *user_data) {
 
261
    struct network_driver *_driverState = user_data;
 
262
 
 
263
    if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS,
 
264
                               "NameOwnerChanged") ||
 
265
        dbus_message_is_signal(message, "org.fedoraproject.FirewallD1",
 
266
                               "Reloaded"))
 
267
    {
 
268
        VIR_DEBUG("Reload in bridge_driver because of firewalld.");
 
269
        networkReloadIptablesRules(_driverState);
 
270
    }
 
271
 
 
272
    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
273
}
 
274
#endif
 
275
 
255
276
/**
256
277
 * networkStartup:
257
278
 *
260
281
static int
261
282
networkStartup(int privileged) {
262
283
    char *base = NULL;
 
284
#ifdef HAVE_FIREWALLD
 
285
    DBusConnection *sysbus = NULL;
 
286
#endif
263
287
 
264
288
    if (VIR_ALLOC(driverState) < 0)
265
289
        goto error;
322
346
 
323
347
    networkFindActiveConfigs(driverState);
324
348
    networkReloadIptablesRules(driverState);
 
349
    networkRefreshDaemons(driverState);
325
350
    networkAutostartConfigs(driverState);
326
351
 
327
352
    networkDriverUnlock(driverState);
328
353
 
 
354
#ifdef HAVE_FIREWALLD
 
355
    if (!(sysbus = virDBusGetSystemBus())) {
 
356
        virErrorPtr err = virGetLastError();
 
357
        VIR_WARN("DBus not available, disabling firewalld support "
 
358
                 "in bridge_driver: %s", err->message);
 
359
    } else {
 
360
        /* add matches for
 
361
         * NameOwnerChanged on org.freedesktop.DBus for firewalld start/stop
 
362
         * Reloaded on org.fedoraproject.FirewallD1 for firewalld reload
 
363
         */
 
364
        dbus_bus_add_match(sysbus,
 
365
                           "type='signal'"
 
366
                           ",interface='"DBUS_INTERFACE_DBUS"'"
 
367
                           ",member='NameOwnerChanged'"
 
368
                           ",arg0='org.fedoraproject.FirewallD1'",
 
369
                           NULL);
 
370
        dbus_bus_add_match(sysbus,
 
371
                           "type='signal'"
 
372
                           ",interface='org.fedoraproject.FirewallD1'"
 
373
                           ",member='Reloaded'",
 
374
                           NULL);
 
375
        dbus_connection_add_filter(sysbus, firewalld_dbus_filter_bridge,
 
376
                                   driverState, NULL);
 
377
    }
 
378
#endif
 
379
 
329
380
    return 0;
330
381
 
331
382
out_of_memory:
356
407
                             driverState->networkConfigDir,
357
408
                             driverState->networkAutostartDir);
358
409
    networkReloadIptablesRules(driverState);
 
410
    networkRefreshDaemons(driverState);
359
411
    networkAutostartConfigs(driverState);
360
412
    networkDriverUnlock(driverState);
361
413
    return 0;
420
472
}
421
473
 
422
474
 
 
475
/* networkKillDaemon:
 
476
 *
 
477
 * kill the specified pid/name, and wait a bit to make sure it's dead.
 
478
 */
 
479
static int
 
480
networkKillDaemon(pid_t pid, const char *daemonName, const char *networkName)
 
481
{
 
482
    int ii, ret = -1;
 
483
    const char *signame = "TERM";
 
484
 
 
485
    /* send SIGTERM, then wait up to 3 seconds for the process to
 
486
     * disappear, send SIGKILL, then wait for up to another 2
 
487
     * seconds. If that fails, log a warning and continue, hoping
 
488
     * for the best.
 
489
     */
 
490
    for (ii = 0; ii < 25; ii++) {
 
491
        int signum = 0;
 
492
        if (ii == 0)
 
493
            signum = SIGTERM;
 
494
        else if (ii == 15) {
 
495
            signum = SIGKILL;
 
496
            signame = "KILL";
 
497
        }
 
498
        if (kill(pid, signum) < 0) {
 
499
            if (errno == ESRCH) {
 
500
                ret = 0;
 
501
            } else {
 
502
                char ebuf[1024];
 
503
                VIR_WARN("Failed to terminate %s process %d "
 
504
                         "for network '%s' with SIG%s: %s",
 
505
                         daemonName, pid, networkName, signame,
 
506
                         virStrerror(errno, ebuf, sizeof(ebuf)));
 
507
            }
 
508
            goto cleanup;
 
509
        }
 
510
        /* NB: since networks have no reference count like
 
511
         * domains, there is no safe way to unlock the network
 
512
         * object temporarily, and so we can't follow the
 
513
         * procedure used by the qemu driver of 1) unlock driver
 
514
         * 2) sleep, 3) add ref to object 4) unlock object, 5)
 
515
         * re-lock driver, 6) re-lock object. We may need to add
 
516
         * that functionality eventually, but for now this
 
517
         * function is rarely used and, at worst, leaving the
 
518
         * network driver locked during this loop of sleeps will
 
519
         * have the effect of holding up any other thread trying
 
520
         * to make modifications to a network for up to 5 seconds;
 
521
         * since modifications to networks are much less common
 
522
         * than modifications to domains, this seems a reasonable
 
523
         * tradeoff in exchange for less code disruption.
 
524
         */
 
525
        usleep(20 * 1000);
 
526
    }
 
527
    VIR_WARN("Timed out waiting after SIG%s to %s process %d "
 
528
             "(network '%s')",
 
529
             signame, daemonName, pid, networkName);
 
530
cleanup:
 
531
    return ret;
 
532
}
 
533
 
423
534
static int
424
535
networkBuildDnsmasqHostsfile(dnsmasqContext *dctx,
425
536
                             virNetworkIpDefPtr ipdef,
484
595
     * very explicit on this.
485
596
     */
486
597
 
487
 
    /*
488
 
     * Run as user libvirt-dnsmasq
489
 
     */
490
 
    virCommandAddArgList(cmd, "-u", "libvirt-dnsmasq", NULL);
 
598
        /*
 
599
         * Run as user libvirt-dnsmasq
 
600
         */
 
601
        virCommandAddArgList(cmd, "-u", "libvirt-dnsmasq", NULL);
491
602
 
492
603
    /*
493
604
     * Needed to ensure dnsmasq uses same algorithm for processing
496
607
    virCommandAddArgList(cmd, "--strict-order", "--bind-interfaces", NULL);
497
608
 
498
609
    if (network->def->domain)
499
 
        virCommandAddArgList(cmd, "--domain", network->def->domain, NULL);
 
610
        virCommandAddArgPair(cmd, "--domain", network->def->domain);
 
611
    /* need to specify local even if no domain specified */
 
612
    virCommandAddArgFormat(cmd, "--local=/%s/",
 
613
                           network->def->domain ? network->def->domain : "");
 
614
    virCommandAddArg(cmd, "--domain-needed");
500
615
 
501
616
    if (pidfile)
502
617
        virCommandAddArgPair(cmd, "--pid-file", pidfile);
641
756
        if (networkBuildDnsmasqHostsfile(dctx, ipdef, network->def->dns) < 0)
642
757
            goto cleanup;
643
758
 
644
 
        if (dctx->hostsfile->nhosts)
 
759
        /* Even if there are currently no static hosts, if we're
 
760
         * listening for DHCP, we should write a 0-length hosts
 
761
         * file to allow for runtime additions.
 
762
         */
 
763
        if (ipdef->nranges || ipdef->nhosts)
645
764
            virCommandAddArgPair(cmd, "--dhcp-hostsfile",
646
765
                                 dctx->hostsfile->path);
647
 
        if (dctx->addnhostsfile->nhosts)
648
 
            virCommandAddArgPair(cmd, "--addn-hosts",
649
 
                                 dctx->addnhostsfile->path);
 
766
 
 
767
        /* Likewise, always create this file and put it on the commandline, to allow for
 
768
         * for runtime additions.
 
769
         */
 
770
        virCommandAddArgPair(cmd, "--addn-hosts",
 
771
                             dctx->addnhostsfile->path);
650
772
 
651
773
        if (ipdef->tftproot) {
652
774
            virCommandAddArgList(cmd, "--enable-tftp",
730
852
    int ret = -1;
731
853
    dnsmasqContext *dctx = NULL;
732
854
 
 
855
    if (!virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, 0)) {
 
856
        /* no IPv6 addresses, so we don't need to run radvd */
 
857
        ret = 0;
 
858
        goto cleanup;
 
859
    }
 
860
 
733
861
    if (virFileMakePath(NETWORK_PID_DIR) < 0) {
734
862
        virReportSystemError(errno,
735
863
                             _("cannot create directory %s"),
793
921
    return ret;
794
922
}
795
923
 
796
 
static int
797
 
networkStartRadvd(virNetworkObjPtr network)
798
 
{
799
 
    char *pidfile = NULL;
800
 
    char *radvdpidbase = NULL;
801
 
    virBuffer configbuf = VIR_BUFFER_INITIALIZER;;
802
 
    char *configstr = NULL;
803
 
    char *configfile = NULL;
804
 
    virCommandPtr cmd = NULL;
805
 
    int ret = -1, ii;
806
 
    virNetworkIpDefPtr ipdef;
807
 
 
808
 
    network->radvdPid = -1;
809
 
 
810
 
    if (!virFileIsExecutable(RADVD)) {
811
 
        virReportSystemError(errno,
812
 
                             _("Cannot find %s - "
813
 
                               "Possibly the package isn't installed"),
814
 
                             RADVD);
815
 
        goto cleanup;
816
 
    }
817
 
 
818
 
    if (virFileMakePath(NETWORK_PID_DIR) < 0) {
819
 
        virReportSystemError(errno,
820
 
                             _("cannot create directory %s"),
821
 
                             NETWORK_PID_DIR);
822
 
        goto cleanup;
823
 
    }
824
 
    if (virFileMakePath(RADVD_STATE_DIR) < 0) {
825
 
        virReportSystemError(errno,
826
 
                             _("cannot create directory %s"),
827
 
                             RADVD_STATE_DIR);
828
 
        goto cleanup;
829
 
    }
830
 
 
831
 
    /* construct pidfile name */
832
 
    if (!(radvdpidbase = networkRadvdPidfileBasename(network->def->name))) {
833
 
        virReportOOMError();
834
 
        goto cleanup;
835
 
    }
836
 
    if (!(pidfile = virPidFileBuildPath(NETWORK_PID_DIR, radvdpidbase))) {
837
 
        virReportOOMError();
838
 
        goto cleanup;
839
 
    }
840
 
 
841
 
    /* create radvd config file appropriate for this network */
 
924
/* networkRefreshDhcpDaemon:
 
925
 *  Update dnsmasq config files, then send a SIGHUP so that it rereads
 
926
 *  them.
 
927
 *
 
928
 *  Returns 0 on success, -1 on failure.
 
929
 */
 
930
static int
 
931
networkRefreshDhcpDaemon(virNetworkObjPtr network)
 
932
{
 
933
    int ret = -1, ii;
 
934
    virNetworkIpDefPtr ipdef;
 
935
    dnsmasqContext *dctx = NULL;
 
936
 
 
937
    /* if there's no running dnsmasq, just start it */
 
938
    if (network->dnsmasqPid <= 0 || (kill(network->dnsmasqPid, 0) < 0))
 
939
        return networkStartDhcpDaemon(network);
 
940
 
 
941
    /* Look for first IPv4 address that has dhcp defined. */
 
942
    /* We support dhcp config on 1 IPv4 interface only. */
 
943
    for (ii = 0;
 
944
         (ipdef = virNetworkDefGetIpByIndex(network->def, AF_INET, ii));
 
945
         ii++) {
 
946
        if (ipdef->nranges || ipdef->nhosts)
 
947
            break;
 
948
    }
 
949
    /* If no IPv4 addresses had dhcp info, pick the first (if there were any). */
 
950
    if (!ipdef)
 
951
        ipdef = virNetworkDefGetIpByIndex(network->def, AF_INET, 0);
 
952
 
 
953
    if (!ipdef) {
 
954
        /* no <ip> elements, so nothing to do */
 
955
        return 0;
 
956
    }
 
957
 
 
958
    if (!(dctx = dnsmasqContextNew(network->def->name, DNSMASQ_STATE_DIR)))
 
959
        goto cleanup;
 
960
 
 
961
    if (networkBuildDnsmasqHostsfile(dctx, ipdef, network->def->dns) < 0)
 
962
       goto cleanup;
 
963
 
 
964
    if ((ret = dnsmasqSave(dctx)) < 0)
 
965
        goto cleanup;
 
966
 
 
967
    ret = kill(network->dnsmasqPid, SIGHUP);
 
968
cleanup:
 
969
    dnsmasqContextFree(dctx);
 
970
    return ret;
 
971
}
 
972
 
 
973
/* networkRestartDhcpDaemon:
 
974
 *
 
975
 * kill and restart dnsmasq, in order to update any config that is on
 
976
 * the dnsmasq commandline (and any placed in separate config files).
 
977
 *
 
978
 *  Returns 0 on success, -1 on failure.
 
979
 */
 
980
static int
 
981
networkRestartDhcpDaemon(virNetworkObjPtr network)
 
982
{
 
983
    /* if there is a running dnsmasq, kill it */
 
984
    if (network->dnsmasqPid > 0) {
 
985
        networkKillDaemon(network->dnsmasqPid, "dnsmasq",
 
986
                          network->def->name);
 
987
        network->dnsmasqPid = -1;
 
988
    }
 
989
    /* now start dnsmasq if it should be started */
 
990
    return networkStartDhcpDaemon(network);
 
991
}
 
992
 
 
993
static int
 
994
networkRadvdConfContents(virNetworkObjPtr network, char **configstr)
 
995
{
 
996
    virBuffer configbuf = VIR_BUFFER_INITIALIZER;
 
997
    int ret = -1, ii;
 
998
    virNetworkIpDefPtr ipdef;
 
999
    bool v6present = false;
 
1000
 
 
1001
    *configstr = NULL;
 
1002
 
 
1003
    /* create radvd config file appropriate for this network;
 
1004
     * IgnoreIfMissing allows radvd to start even when the bridge is down
 
1005
     */
842
1006
    virBufferAsprintf(&configbuf, "interface %s\n"
843
1007
                      "{\n"
844
1008
                      "  AdvSendAdvert on;\n"
845
1009
                      "  AdvManagedFlag off;\n"
846
1010
                      "  AdvOtherConfigFlag off;\n"
 
1011
                      "  IgnoreIfMissing on;\n"
847
1012
                      "\n",
848
1013
                      network->def->bridge);
 
1014
 
 
1015
    /* add a section for each IPv6 address in the config */
849
1016
    for (ii = 0;
850
1017
         (ipdef = virNetworkDefGetIpByIndex(network->def, AF_INET6, ii));
851
1018
         ii++) {
852
1019
        int prefix;
853
1020
        char *netaddr;
854
1021
 
 
1022
        v6present = true;
855
1023
        prefix = virNetworkIpDefPrefix(ipdef);
856
1024
        if (prefix < 0) {
857
 
            networkReportError(VIR_ERR_INTERNAL_ERROR,
858
 
                               _("bridge  '%s' has an invalid prefix"),
859
 
                               network->def->bridge);
 
1025
            virReportError(VIR_ERR_INTERNAL_ERROR,
 
1026
                           _("bridge '%s' has an invalid prefix"),
 
1027
                           network->def->bridge);
860
1028
            goto cleanup;
861
1029
        }
862
1030
        if (!(netaddr = virSocketAddrFormat(&ipdef->address)))
872
1040
        VIR_FREE(netaddr);
873
1041
    }
874
1042
 
875
 
    virBufferAddLit(&configbuf, "};\n");
876
 
 
877
 
    if (virBufferError(&configbuf)) {
878
 
        virReportOOMError();
 
1043
    /* only create the string if we found at least one IPv6 address */
 
1044
    if (v6present) {
 
1045
        virBufferAddLit(&configbuf, "};\n");
 
1046
 
 
1047
        if (virBufferError(&configbuf)) {
 
1048
            virReportOOMError();
 
1049
            goto cleanup;
 
1050
        }
 
1051
        if (!(*configstr = virBufferContentAndReset(&configbuf))) {
 
1052
            virReportOOMError();
 
1053
            goto cleanup;
 
1054
        }
 
1055
    }
 
1056
 
 
1057
    ret = 0;
 
1058
cleanup:
 
1059
    virBufferFreeAndReset(&configbuf);
 
1060
    return ret;
 
1061
}
 
1062
 
 
1063
/* write file and return it's name (which must be freed by caller) */
 
1064
static int
 
1065
networkRadvdConfWrite(virNetworkObjPtr network, char **configFile)
 
1066
{
 
1067
    int ret = -1;
 
1068
    char *configStr = NULL;
 
1069
    char *myConfigFile = NULL;
 
1070
 
 
1071
    if (!configFile)
 
1072
        configFile = &myConfigFile;
 
1073
 
 
1074
    *configFile = NULL;
 
1075
 
 
1076
    if (networkRadvdConfContents(network, &configStr) < 0)
879
1077
        goto cleanup;
880
 
    }
881
 
    if (!(configstr = virBufferContentAndReset(&configbuf))) {
882
 
        virReportOOMError();
 
1078
 
 
1079
    if (!configStr) {
 
1080
        ret = 0;
883
1081
        goto cleanup;
884
1082
    }
885
1083
 
886
1084
    /* construct the filename */
887
 
    if (!(configfile = networkRadvdConfigFileName(network->def->name))) {
 
1085
    if (!(*configFile = networkRadvdConfigFileName(network->def->name))) {
888
1086
        virReportOOMError();
889
1087
        goto cleanup;
890
1088
    }
891
1089
    /* write the file */
892
 
    if (virFileWriteStr(configfile, configstr, 0600) < 0) {
 
1090
    if (virFileWriteStr(*configFile, configStr, 0600) < 0) {
893
1091
        virReportSystemError(errno,
894
1092
                             _("couldn't write radvd config file '%s'"),
895
 
                             configfile);
896
 
        goto cleanup;
897
 
    }
 
1093
                             *configFile);
 
1094
        goto cleanup;
 
1095
    }
 
1096
 
 
1097
    ret = 0;
 
1098
cleanup:
 
1099
    VIR_FREE(configStr);
 
1100
    VIR_FREE(myConfigFile);
 
1101
    return ret;
 
1102
}
 
1103
 
 
1104
static int
 
1105
networkStartRadvd(virNetworkObjPtr network)
 
1106
{
 
1107
    char *pidfile = NULL;
 
1108
    char *radvdpidbase = NULL;
 
1109
    char *configfile = NULL;
 
1110
    virCommandPtr cmd = NULL;
 
1111
    int ret = -1;
 
1112
 
 
1113
    network->radvdPid = -1;
 
1114
 
 
1115
    if (!virNetworkDefGetIpByIndex(network->def, AF_INET6, 0)) {
 
1116
        /* no IPv6 addresses, so we don't need to run radvd */
 
1117
        ret = 0;
 
1118
        goto cleanup;
 
1119
    }
 
1120
 
 
1121
    if (!virFileIsExecutable(RADVD)) {
 
1122
        virReportSystemError(errno,
 
1123
                             _("Cannot find %s - "
 
1124
                               "Possibly the package isn't installed"),
 
1125
                             RADVD);
 
1126
        goto cleanup;
 
1127
    }
 
1128
 
 
1129
    if (virFileMakePath(NETWORK_PID_DIR) < 0) {
 
1130
        virReportSystemError(errno,
 
1131
                             _("cannot create directory %s"),
 
1132
                             NETWORK_PID_DIR);
 
1133
        goto cleanup;
 
1134
    }
 
1135
    if (virFileMakePath(RADVD_STATE_DIR) < 0) {
 
1136
        virReportSystemError(errno,
 
1137
                             _("cannot create directory %s"),
 
1138
                             RADVD_STATE_DIR);
 
1139
        goto cleanup;
 
1140
    }
 
1141
 
 
1142
    /* construct pidfile name */
 
1143
    if (!(radvdpidbase = networkRadvdPidfileBasename(network->def->name))) {
 
1144
        virReportOOMError();
 
1145
        goto cleanup;
 
1146
    }
 
1147
    if (!(pidfile = virPidFileBuildPath(NETWORK_PID_DIR, radvdpidbase))) {
 
1148
        virReportOOMError();
 
1149
        goto cleanup;
 
1150
    }
 
1151
 
 
1152
    if (networkRadvdConfWrite(network, &configfile) < 0)
 
1153
        goto cleanup;
898
1154
 
899
1155
    /* prevent radvd from daemonizing itself with "--debug 1", and use
900
1156
     * a dummy pidfile name - virCommand will create the pidfile we
916
1172
    if (virCommandRun(cmd, NULL) < 0)
917
1173
        goto cleanup;
918
1174
 
919
 
    if (virPidFileRead(NETWORK_PID_DIR, radvdpidbase,
920
 
                       &network->radvdPid) < 0)
 
1175
    if (virPidFileRead(NETWORK_PID_DIR, radvdpidbase, &network->radvdPid) < 0)
921
1176
        goto cleanup;
922
1177
 
923
1178
    ret = 0;
924
1179
cleanup:
925
1180
    virCommandFree(cmd);
926
1181
    VIR_FREE(configfile);
927
 
    VIR_FREE(configstr);
928
 
    virBufferFreeAndReset(&configbuf);
929
1182
    VIR_FREE(radvdpidbase);
930
1183
    VIR_FREE(pidfile);
931
1184
    return ret;
932
1185
}
933
1186
 
934
1187
static int
 
1188
networkRefreshRadvd(virNetworkObjPtr network)
 
1189
{
 
1190
    /* if there's no running radvd, just start it */
 
1191
    if (network->radvdPid <= 0 || (kill(network->radvdPid, 0) < 0))
 
1192
        return networkStartRadvd(network);
 
1193
 
 
1194
    if (!virNetworkDefGetIpByIndex(network->def, AF_INET6, 0)) {
 
1195
        /* no IPv6 addresses, so we don't need to run radvd */
 
1196
        return 0;
 
1197
    }
 
1198
 
 
1199
    if (networkRadvdConfWrite(network, NULL) < 0)
 
1200
        return -1;
 
1201
 
 
1202
    return kill(network->radvdPid, SIGHUP);
 
1203
}
 
1204
 
 
1205
#if 0
 
1206
/* currently unused, so it causes a build error unless we #if it out */
 
1207
static int
 
1208
networkRestartRadvd(virNetworkObjPtr network)
 
1209
{
 
1210
    char *radvdpidbase;
 
1211
 
 
1212
    /* if there is a running radvd, kill it */
 
1213
    if (network->radvdPid > 0) {
 
1214
        /* essentially ignore errors from the following two functions,
 
1215
         * since there's really no better recovery to be done than to
 
1216
         * just push ahead (and that may be exactly what's needed).
 
1217
         */
 
1218
        if ((networkKillDaemon(network->dnsmasqPid, "radvd",
 
1219
                               network->def->name) >= 0) &&
 
1220
            ((radvdpidbase = networkRadvdPidfileBasename(network->def->name))
 
1221
             != NULL)) {
 
1222
            virPidFileDelete(NETWORK_PID_DIR, radvdpidbase);
 
1223
            VIR_FREE(radvdpidbase);
 
1224
        }
 
1225
        network->radvdPid = -1;
 
1226
    }
 
1227
    /* now start radvd if it should be started */
 
1228
    return networkStartRadvd(network);
 
1229
}
 
1230
#endif /* #if 0 */
 
1231
 
 
1232
/* SIGHUP/restart any dnsmasq or radvd daemons.
 
1233
 * This should be called when libvirtd is restarted.
 
1234
 */
 
1235
static void
 
1236
networkRefreshDaemons(struct network_driver *driver)
 
1237
{
 
1238
    unsigned int i;
 
1239
 
 
1240
    VIR_INFO("Refreshing network daemons");
 
1241
 
 
1242
    for (i = 0 ; i < driver->networks.count ; i++) {
 
1243
        virNetworkObjPtr network = driver->networks.objs[i];
 
1244
 
 
1245
        virNetworkObjLock(network);
 
1246
        if (virNetworkObjIsActive(network) &&
 
1247
            ((network->def->forwardType == VIR_NETWORK_FORWARD_NONE) ||
 
1248
             (network->def->forwardType == VIR_NETWORK_FORWARD_NAT) ||
 
1249
             (network->def->forwardType == VIR_NETWORK_FORWARD_ROUTE))) {
 
1250
            /* Only the three L3 network types that are configured by
 
1251
             * libvirt will have a dnsmasq or radvd daemon associated
 
1252
             * with them.  Here we send a SIGHUP to an existing
 
1253
             * dnsmasq and/or radvd, or restart them if they've
 
1254
             * disappeared.
 
1255
             */
 
1256
            networkRefreshDhcpDaemon(network);
 
1257
            networkRefreshRadvd(network);
 
1258
        }
 
1259
        virNetworkObjUnlock(network);
 
1260
    }
 
1261
}
 
1262
 
 
1263
static int
935
1264
networkAddMasqueradingIptablesRules(struct network_driver *driver,
936
1265
                                    virNetworkObjPtr network,
937
1266
                                    virNetworkIpDefPtr ipdef)
940
1269
    const char *forwardIf = virNetworkDefForwardIf(network->def, 0);
941
1270
 
942
1271
    if (prefix < 0) {
943
 
        networkReportError(VIR_ERR_INTERNAL_ERROR,
944
 
                           _("Invalid prefix or netmask for '%s'"),
945
 
                           network->def->bridge);
 
1272
        virReportError(VIR_ERR_INTERNAL_ERROR,
 
1273
                       _("Invalid prefix or netmask for '%s'"),
 
1274
                       network->def->bridge);
946
1275
        goto masqerr1;
947
1276
    }
948
1277
 
952
1281
                                   prefix,
953
1282
                                   network->def->bridge,
954
1283
                                   forwardIf) < 0) {
955
 
        networkReportError(VIR_ERR_SYSTEM_ERROR,
956
 
                           _("failed to add iptables rule to allow forwarding from '%s'"),
957
 
                           network->def->bridge);
 
1284
        virReportError(VIR_ERR_SYSTEM_ERROR,
 
1285
                       _("failed to add iptables rule to allow forwarding from '%s'"),
 
1286
                       network->def->bridge);
958
1287
        goto masqerr1;
959
1288
    }
960
1289
 
966
1295
                                         prefix,
967
1296
                                         network->def->bridge,
968
1297
                                         forwardIf) < 0) {
969
 
        networkReportError(VIR_ERR_SYSTEM_ERROR,
970
 
                           _("failed to add iptables rule to allow forwarding to '%s'"),
971
 
                           network->def->bridge);
 
1298
        virReportError(VIR_ERR_SYSTEM_ERROR,
 
1299
                       _("failed to add iptables rule to allow forwarding to '%s'"),
 
1300
                       network->def->bridge);
972
1301
        goto masqerr2;
973
1302
    }
974
1303
 
1001
1330
                                     prefix,
1002
1331
                                     forwardIf,
1003
1332
                                     NULL) < 0) {
1004
 
        networkReportError(VIR_ERR_SYSTEM_ERROR,
1005
 
                           forwardIf ?
1006
 
                           _("failed to add iptables rule to enable masquerading to %s") :
1007
 
                           _("failed to add iptables rule to enable masquerading"),
1008
 
                           forwardIf);
 
1333
        virReportError(VIR_ERR_SYSTEM_ERROR,
 
1334
                       forwardIf ?
 
1335
                       _("failed to add iptables rule to enable masquerading to %s") :
 
1336
                       _("failed to add iptables rule to enable masquerading"),
 
1337
                       forwardIf);
1009
1338
        goto masqerr3;
1010
1339
    }
1011
1340
 
1015
1344
                                     prefix,
1016
1345
                                     forwardIf,
1017
1346
                                     "udp") < 0) {
1018
 
        networkReportError(VIR_ERR_SYSTEM_ERROR,
1019
 
                           forwardIf ?
1020
 
                           _("failed to add iptables rule to enable UDP masquerading to %s") :
1021
 
                           _("failed to add iptables rule to enable UDP masquerading"),
1022
 
                           forwardIf);
 
1347
        virReportError(VIR_ERR_SYSTEM_ERROR,
 
1348
                       forwardIf ?
 
1349
                       _("failed to add iptables rule to enable UDP masquerading to %s") :
 
1350
                       _("failed to add iptables rule to enable UDP masquerading"),
 
1351
                       forwardIf);
1023
1352
        goto masqerr4;
1024
1353
    }
1025
1354
 
1029
1358
                                     prefix,
1030
1359
                                     forwardIf,
1031
1360
                                     "tcp") < 0) {
1032
 
        networkReportError(VIR_ERR_SYSTEM_ERROR,
1033
 
                           forwardIf ?
1034
 
                           _("failed to add iptables rule to enable TCP masquerading to %s") :
1035
 
                           _("failed to add iptables rule to enable TCP masquerading"),
1036
 
                           forwardIf);
 
1361
        virReportError(VIR_ERR_SYSTEM_ERROR,
 
1362
                       forwardIf ?
 
1363
                       _("failed to add iptables rule to enable TCP masquerading to %s") :
 
1364
                       _("failed to add iptables rule to enable TCP masquerading"),
 
1365
                       forwardIf);
1037
1366
        goto masqerr5;
1038
1367
    }
1039
1368
 
1114
1443
    const char *forwardIf = virNetworkDefForwardIf(network->def, 0);
1115
1444
 
1116
1445
    if (prefix < 0) {
1117
 
        networkReportError(VIR_ERR_INTERNAL_ERROR,
1118
 
                           _("Invalid prefix or netmask for '%s'"),
1119
 
                           network->def->bridge);
 
1446
        virReportError(VIR_ERR_INTERNAL_ERROR,
 
1447
                       _("Invalid prefix or netmask for '%s'"),
 
1448
                       network->def->bridge);
1120
1449
        goto routeerr1;
1121
1450
    }
1122
1451
 
1126
1455
                                   prefix,
1127
1456
                                   network->def->bridge,
1128
1457
                                   forwardIf) < 0) {
1129
 
        networkReportError(VIR_ERR_SYSTEM_ERROR,
1130
 
                           _("failed to add iptables rule to allow routing from '%s'"),
1131
 
                           network->def->bridge);
 
1458
        virReportError(VIR_ERR_SYSTEM_ERROR,
 
1459
                       _("failed to add iptables rule to allow routing from '%s'"),
 
1460
                       network->def->bridge);
1132
1461
        goto routeerr1;
1133
1462
    }
1134
1463
 
1138
1467
                                  prefix,
1139
1468
                                  network->def->bridge,
1140
1469
                                  forwardIf) < 0) {
1141
 
        networkReportError(VIR_ERR_SYSTEM_ERROR,
1142
 
                           _("failed to add iptables rule to allow routing to '%s'"),
1143
 
                           network->def->bridge);
 
1470
        virReportError(VIR_ERR_SYSTEM_ERROR,
 
1471
                       _("failed to add iptables rule to allow routing to '%s'"),
 
1472
                       network->def->bridge);
1144
1473
        goto routeerr2;
1145
1474
    }
1146
1475
 
1192
1521
 
1193
1522
    if (iptablesAddForwardRejectOut(driver->iptables, AF_INET6,
1194
1523
                                    network->def->bridge) < 0) {
1195
 
        networkReportError(VIR_ERR_SYSTEM_ERROR,
1196
 
                           _("failed to add ip6tables rule to block outbound traffic from '%s'"),
1197
 
                           network->def->bridge);
 
1524
        virReportError(VIR_ERR_SYSTEM_ERROR,
 
1525
                       _("failed to add ip6tables rule to block outbound traffic from '%s'"),
 
1526
                       network->def->bridge);
1198
1527
        goto err1;
1199
1528
    }
1200
1529
 
1201
1530
    if (iptablesAddForwardRejectIn(driver->iptables, AF_INET6,
1202
1531
                                   network->def->bridge) < 0) {
1203
 
        networkReportError(VIR_ERR_SYSTEM_ERROR,
1204
 
                           _("failed to add ip6tables rule to block inbound traffic to '%s'"),
1205
 
                           network->def->bridge);
 
1532
        virReportError(VIR_ERR_SYSTEM_ERROR,
 
1533
                       _("failed to add ip6tables rule to block inbound traffic to '%s'"),
 
1534
                       network->def->bridge);
1206
1535
        goto err2;
1207
1536
    }
1208
1537
 
1209
1538
    /* Allow traffic between guests on the same bridge */
1210
1539
    if (iptablesAddForwardAllowCross(driver->iptables, AF_INET6,
1211
1540
                                     network->def->bridge) < 0) {
1212
 
        networkReportError(VIR_ERR_SYSTEM_ERROR,
1213
 
                           _("failed to add ip6tables rule to allow cross bridge traffic on '%s'"),
1214
 
                           network->def->bridge);
 
1541
        virReportError(VIR_ERR_SYSTEM_ERROR,
 
1542
                       _("failed to add ip6tables rule to allow cross bridge traffic on '%s'"),
 
1543
                       network->def->bridge);
1215
1544
        goto err3;
1216
1545
    }
1217
1546
 
1218
1547
    /* allow DNS over IPv6 */
1219
1548
    if (iptablesAddTcpInput(driver->iptables, AF_INET6,
1220
1549
                            network->def->bridge, 53) < 0) {
1221
 
        networkReportError(VIR_ERR_SYSTEM_ERROR,
1222
 
                           _("failed to add ip6tables rule to allow DNS requests from '%s'"),
1223
 
                           network->def->bridge);
 
1550
        virReportError(VIR_ERR_SYSTEM_ERROR,
 
1551
                       _("failed to add ip6tables rule to allow DNS requests from '%s'"),
 
1552
                       network->def->bridge);
1224
1553
        goto err4;
1225
1554
    }
1226
1555
 
1227
1556
    if (iptablesAddUdpInput(driver->iptables, AF_INET6,
1228
1557
                            network->def->bridge, 53) < 0) {
1229
 
        networkReportError(VIR_ERR_SYSTEM_ERROR,
1230
 
                           _("failed to add ip6tables rule to allow DNS requests from '%s'"),
1231
 
                           network->def->bridge);
 
1558
        virReportError(VIR_ERR_SYSTEM_ERROR,
 
1559
                       _("failed to add ip6tables rule to allow DNS requests from '%s'"),
 
1560
                       network->def->bridge);
1232
1561
        goto err5;
1233
1562
    }
1234
1563
 
1254
1583
    if (!virNetworkDefGetIpByIndex(network->def, AF_INET6, 0))
1255
1584
        return;
1256
1585
 
 
1586
    iptablesRemoveUdpInput(driver->iptables, AF_INET6, network->def->bridge, 53);
 
1587
    iptablesRemoveTcpInput(driver->iptables, AF_INET6, network->def->bridge, 53);
1257
1588
    iptablesRemoveForwardAllowCross(driver->iptables, AF_INET6, network->def->bridge);
1258
1589
    iptablesRemoveForwardRejectIn(driver->iptables, AF_INET6, network->def->bridge);
1259
1590
    iptablesRemoveForwardRejectOut(driver->iptables, AF_INET6, network->def->bridge);
1279
1610
 
1280
1611
    if (iptablesAddTcpInput(driver->iptables, AF_INET,
1281
1612
                            network->def->bridge, 67) < 0) {
1282
 
        networkReportError(VIR_ERR_SYSTEM_ERROR,
1283
 
                           _("failed to add iptables rule to allow DHCP requests from '%s'"),
1284
 
                           network->def->bridge);
 
1613
        virReportError(VIR_ERR_SYSTEM_ERROR,
 
1614
                       _("failed to add iptables rule to allow DHCP requests from '%s'"),
 
1615
                       network->def->bridge);
1285
1616
        goto err1;
1286
1617
    }
1287
1618
 
1288
1619
    if (iptablesAddUdpInput(driver->iptables, AF_INET,
1289
1620
                            network->def->bridge, 67) < 0) {
1290
 
        networkReportError(VIR_ERR_SYSTEM_ERROR,
1291
 
                           _("failed to add iptables rule to allow DHCP requests from '%s'"),
1292
 
                           network->def->bridge);
 
1621
        virReportError(VIR_ERR_SYSTEM_ERROR,
 
1622
                       _("failed to add iptables rule to allow DHCP requests from '%s'"),
 
1623
                       network->def->bridge);
1293
1624
        goto err2;
1294
1625
    }
1295
1626
 
1310
1641
    /* allow DNS requests through to dnsmasq */
1311
1642
    if (iptablesAddTcpInput(driver->iptables, AF_INET,
1312
1643
                            network->def->bridge, 53) < 0) {
1313
 
        networkReportError(VIR_ERR_SYSTEM_ERROR,
1314
 
                           _("failed to add iptables rule to allow DNS requests from '%s'"),
1315
 
                           network->def->bridge);
 
1644
        virReportError(VIR_ERR_SYSTEM_ERROR,
 
1645
                       _("failed to add iptables rule to allow DNS requests from '%s'"),
 
1646
                       network->def->bridge);
1316
1647
        goto err3;
1317
1648
    }
1318
1649
 
1319
1650
    if (iptablesAddUdpInput(driver->iptables, AF_INET,
1320
1651
                            network->def->bridge, 53) < 0) {
1321
 
        networkReportError(VIR_ERR_SYSTEM_ERROR,
1322
 
                           _("failed to add iptables rule to allow DNS requests from '%s'"),
1323
 
                           network->def->bridge);
 
1652
        virReportError(VIR_ERR_SYSTEM_ERROR,
 
1653
                       _("failed to add iptables rule to allow DNS requests from '%s'"),
 
1654
                       network->def->bridge);
1324
1655
        goto err4;
1325
1656
    }
1326
1657
 
1328
1659
    if (ipv4def && ipv4def->tftproot &&
1329
1660
        iptablesAddUdpInput(driver->iptables, AF_INET,
1330
1661
                            network->def->bridge, 69) < 0) {
1331
 
        networkReportError(VIR_ERR_SYSTEM_ERROR,
1332
 
                           _("failed to add iptables rule to allow TFTP requests from '%s'"),
1333
 
                           network->def->bridge);
 
1662
        virReportError(VIR_ERR_SYSTEM_ERROR,
 
1663
                       _("failed to add iptables rule to allow TFTP requests from '%s'"),
 
1664
                       network->def->bridge);
1334
1665
        goto err5;
1335
1666
    }
1336
1667
 
1338
1669
 
1339
1670
    if (iptablesAddForwardRejectOut(driver->iptables, AF_INET,
1340
1671
                                    network->def->bridge) < 0) {
1341
 
        networkReportError(VIR_ERR_SYSTEM_ERROR,
1342
 
                           _("failed to add iptables rule to block outbound traffic from '%s'"),
1343
 
                           network->def->bridge);
 
1672
        virReportError(VIR_ERR_SYSTEM_ERROR,
 
1673
                       _("failed to add iptables rule to block outbound traffic from '%s'"),
 
1674
                       network->def->bridge);
1344
1675
        goto err6;
1345
1676
    }
1346
1677
 
1347
1678
    if (iptablesAddForwardRejectIn(driver->iptables, AF_INET,
1348
1679
                                   network->def->bridge) < 0) {
1349
 
        networkReportError(VIR_ERR_SYSTEM_ERROR,
1350
 
                           _("failed to add iptables rule to block inbound traffic to '%s'"),
1351
 
                           network->def->bridge);
 
1680
        virReportError(VIR_ERR_SYSTEM_ERROR,
 
1681
                       _("failed to add iptables rule to block inbound traffic to '%s'"),
 
1682
                       network->def->bridge);
1352
1683
        goto err7;
1353
1684
    }
1354
1685
 
1355
1686
    /* Allow traffic between guests on the same bridge */
1356
1687
    if (iptablesAddForwardAllowCross(driver->iptables, AF_INET,
1357
1688
                                     network->def->bridge) < 0) {
1358
 
        networkReportError(VIR_ERR_SYSTEM_ERROR,
1359
 
                           _("failed to add iptables rule to allow cross bridge traffic on '%s'"),
1360
 
                           network->def->bridge);
 
1689
        virReportError(VIR_ERR_SYSTEM_ERROR,
 
1690
                       _("failed to add iptables rule to allow cross bridge traffic on '%s'"),
 
1691
                       network->def->bridge);
1361
1692
        goto err8;
1362
1693
    }
1363
1694
 
1705
2036
 
1706
2037
            if ((net_dest == addr_val) &&
1707
2038
                (netmask.data.inet4.sin_addr.s_addr == mask_val)) {
1708
 
                networkReportError(VIR_ERR_INTERNAL_ERROR,
1709
 
                                   _("Network is already in use by interface %s"),
1710
 
                                   iface);
 
2039
                virReportError(VIR_ERR_INTERNAL_ERROR,
 
2040
                               _("Network is already in use by interface %s"),
 
2041
                               iface);
1711
2042
                ret = -1;
1712
2043
                goto out;
1713
2044
            }
1726
2057
    int prefix = virNetworkIpDefPrefix(ipdef);
1727
2058
 
1728
2059
    if (prefix < 0) {
1729
 
        networkReportError(VIR_ERR_INTERNAL_ERROR,
1730
 
                           _("bridge '%s' has an invalid netmask or IP address"),
1731
 
                           network->def->bridge);
 
2060
        virReportError(VIR_ERR_INTERNAL_ERROR,
 
2061
                       _("bridge '%s' has an invalid netmask or IP address"),
 
2062
                       network->def->bridge);
1732
2063
        return -1;
1733
2064
    }
1734
2065
 
1748
2079
    virErrorPtr save_err = NULL;
1749
2080
    virNetworkIpDefPtr ipdef;
1750
2081
    char *macTapIfName = NULL;
 
2082
    int tapfd = -1;
1751
2083
 
1752
2084
    /* Check to see if any network IP collides with an existing route */
1753
2085
    if (networkCheckRouteCollision(network) < 0)
1769
2101
            virReportOOMError();
1770
2102
            goto err0;
1771
2103
        }
 
2104
        /* Keep tun fd open and interface up to allow for IPv6 DAD to happen */
1772
2105
        if (virNetDevTapCreateInBridgePort(network->def->bridge,
1773
 
                                           &macTapIfName, network->def->mac,
1774
 
                                           NULL, NULL, NULL,
1775
 
                                           VIR_NETDEV_TAP_CREATE_USE_MAC_FOR_BRIDGE) < 0) {
 
2106
                                           &macTapIfName, &network->def->mac,
 
2107
                                           NULL, &tapfd, NULL, NULL,
 
2108
                                           VIR_NETDEV_TAP_CREATE_USE_MAC_FOR_BRIDGE |
 
2109
                                           VIR_NETDEV_TAP_CREATE_IFUP |
 
2110
                                           VIR_NETDEV_TAP_CREATE_PERSIST) < 0) {
1776
2111
            VIR_FREE(macTapIfName);
1777
2112
            goto err0;
1778
2113
        }
1779
2114
    }
1780
2115
 
1781
2116
    /* Set bridge options */
 
2117
 
 
2118
    /* delay is configured in seconds, but virNetDevBridgeSetSTPDelay
 
2119
     * expects milliseconds
 
2120
     */
1782
2121
    if (virNetDevBridgeSetSTPDelay(network->def->bridge,
1783
 
                          network->def->delay) < 0)
 
2122
                                   network->def->delay * 1000) < 0)
1784
2123
        goto err1;
1785
2124
 
1786
2125
    if (virNetDevBridgeSetSTP(network->def->bridge,
1832
2171
    if (v6present && networkStartRadvd(network) < 0)
1833
2172
        goto err4;
1834
2173
 
 
2174
    /* DAD has happened (dnsmasq waits for it), dnsmasq is now bound to the
 
2175
     * bridge's IPv6 address, so we can now set the dummy tun down.
 
2176
     */
 
2177
    if (tapfd >= 0) {
 
2178
        if (virNetDevSetOnline(macTapIfName, false) < 0)
 
2179
            goto err4;
 
2180
        VIR_FORCE_CLOSE(tapfd);
 
2181
    }
 
2182
 
1835
2183
    if (virNetDevBandwidthSet(network->def->bridge, network->def->bandwidth) < 0) {
1836
 
        networkReportError(VIR_ERR_INTERNAL_ERROR,
1837
 
                           _("cannot set bandwidth limits on %s"),
1838
 
                           network->def->bridge);
 
2184
        virReportError(VIR_ERR_INTERNAL_ERROR,
 
2185
                       _("cannot set bandwidth limits on %s"),
 
2186
                       network->def->bridge);
1839
2187
        goto err5;
1840
2188
    }
1841
2189
 
1844
2192
    return 0;
1845
2193
 
1846
2194
 err5:
1847
 
    ignore_value(virNetDevBandwidthClear(network->def->bridge));
 
2195
    virNetDevBandwidthClear(network->def->bridge);
1848
2196
 
1849
2197
 err4:
1850
2198
    if (!save_err)
1870
2218
        save_err = virSaveLastError();
1871
2219
 
1872
2220
    if (macTapIfName) {
 
2221
        VIR_FORCE_CLOSE(tapfd);
1873
2222
        ignore_value(virNetDevTapDelete(macTapIfName));
1874
2223
        VIR_FREE(macTapIfName);
1875
2224
    }
1889
2238
static int networkShutdownNetworkVirtual(struct network_driver *driver,
1890
2239
                                        virNetworkObjPtr network)
1891
2240
{
1892
 
    ignore_value(virNetDevBandwidthClear(network->def->bridge));
 
2241
    virNetDevBandwidthClear(network->def->bridge);
1893
2242
 
1894
2243
    if (network->radvdPid > 0) {
1895
2244
        char *radvdpidbase;
1942
2291
                            virNetworkObjPtr network ATTRIBUTE_UNUSED)
1943
2292
{
1944
2293
    /* put anything here that needs to be done each time a network of
1945
 
     * type BRIDGE, PRIVATE, VEPA, or PASSTHROUGH is started. On
 
2294
     * type BRIDGE, PRIVATE, VEPA, HOSTDEV or PASSTHROUGH is started. On
1946
2295
     * failure, undo anything you've done, and return -1. On success
1947
2296
     * return 0.
1948
2297
     */
1953
2302
                                        virNetworkObjPtr network ATTRIBUTE_UNUSED)
1954
2303
{
1955
2304
    /* put anything here that needs to be done each time a network of
1956
 
     * type BRIDGE, PRIVATE, VEPA, or PASSTHROUGH is shutdown. On
 
2305
     * type BRIDGE, PRIVATE, VEPA, HOSTDEV or PASSTHROUGH is shutdown. On
1957
2306
     * failure, undo anything you've done, and return -1. On success
1958
2307
     * return 0.
1959
2308
     */
1967
2316
    int ret = 0;
1968
2317
 
1969
2318
    if (virNetworkObjIsActive(network)) {
1970
 
        networkReportError(VIR_ERR_OPERATION_INVALID,
1971
 
                           "%s", _("network is already active"));
 
2319
        virReportError(VIR_ERR_OPERATION_INVALID,
 
2320
                       "%s", _("network is already active"));
1972
2321
        return -1;
1973
2322
    }
1974
2323
 
 
2324
    if (virNetworkObjSetDefTransient(network, true) < 0)
 
2325
        return -1;
 
2326
 
1975
2327
    switch (network->def->forwardType) {
1976
2328
 
1977
2329
    case VIR_NETWORK_FORWARD_NONE:
1984
2336
    case VIR_NETWORK_FORWARD_PRIVATE:
1985
2337
    case VIR_NETWORK_FORWARD_VEPA:
1986
2338
    case VIR_NETWORK_FORWARD_PASSTHROUGH:
 
2339
    case VIR_NETWORK_FORWARD_HOSTDEV:
1987
2340
        ret = networkStartNetworkExternal(driver, network);
1988
2341
        break;
1989
2342
    }
1990
2343
 
1991
 
    if (ret < 0)
 
2344
    if (ret < 0) {
 
2345
        virNetworkObjUnsetDefTransient(network);
1992
2346
        return ret;
 
2347
    }
1993
2348
 
1994
2349
    /* Persist the live configuration now that anything autogenerated
1995
2350
     * is setup.
1996
2351
     */
1997
 
    if ((ret = virNetworkSaveConfig(NETWORK_STATE_DIR, network->def)) < 0) {
 
2352
    if ((ret = virNetworkSaveStatus(NETWORK_STATE_DIR, network)) < 0) {
1998
2353
        goto error;
1999
2354
    }
2000
2355
 
2043
2398
    case VIR_NETWORK_FORWARD_PRIVATE:
2044
2399
    case VIR_NETWORK_FORWARD_VEPA:
2045
2400
    case VIR_NETWORK_FORWARD_PASSTHROUGH:
 
2401
    case VIR_NETWORK_FORWARD_HOSTDEV:
2046
2402
        ret = networkShutdownNetworkExternal(driver, network);
2047
2403
        break;
2048
2404
    }
2049
2405
 
2050
2406
    network->active = 0;
2051
 
 
2052
 
    if (network->newDef) {
2053
 
        virNetworkDefFree(network->def);
2054
 
        network->def = network->newDef;
2055
 
        network->newDef = NULL;
2056
 
    }
2057
 
 
 
2407
    virNetworkObjUnsetDefTransient(network);
2058
2408
    return ret;
2059
2409
}
2060
2410
 
2069
2419
    network = virNetworkFindByUUID(&driver->networks, uuid);
2070
2420
    networkDriverUnlock(driver);
2071
2421
    if (!network) {
2072
 
        networkReportError(VIR_ERR_NO_NETWORK,
2073
 
                           "%s", _("no network with matching uuid"));
 
2422
        virReportError(VIR_ERR_NO_NETWORK,
 
2423
                       "%s", _("no network with matching uuid"));
2074
2424
        goto cleanup;
2075
2425
    }
2076
2426
 
2092
2442
    network = virNetworkFindByName(&driver->networks, name);
2093
2443
    networkDriverUnlock(driver);
2094
2444
    if (!network) {
2095
 
        networkReportError(VIR_ERR_NO_NETWORK,
2096
 
                           _("no network with matching name '%s'"), name);
 
2445
        virReportError(VIR_ERR_NO_NETWORK,
 
2446
                       _("no network with matching name '%s'"), name);
2097
2447
        goto cleanup;
2098
2448
    }
2099
2449
 
2210
2560
    return -1;
2211
2561
}
2212
2562
 
 
2563
static int
 
2564
networkListAllNetworks(virConnectPtr conn,
 
2565
                       virNetworkPtr **nets,
 
2566
                       unsigned int flags)
 
2567
{
 
2568
    struct network_driver *driver = conn->networkPrivateData;
 
2569
    int ret = -1;
 
2570
 
 
2571
    virCheckFlags(VIR_CONNECT_LIST_NETWORKS_FILTERS_ALL, -1);
 
2572
 
 
2573
    networkDriverLock(driver);
 
2574
    ret = virNetworkList(conn, driver->networks, nets, flags);
 
2575
    networkDriverUnlock(driver);
 
2576
 
 
2577
    return ret;
 
2578
}
2213
2579
 
2214
2580
static int networkIsActive(virNetworkPtr net)
2215
2581
{
2221
2587
    obj = virNetworkFindByUUID(&driver->networks, net->uuid);
2222
2588
    networkDriverUnlock(driver);
2223
2589
    if (!obj) {
2224
 
        networkReportError(VIR_ERR_NO_NETWORK, NULL);
 
2590
        virReportError(VIR_ERR_NO_NETWORK, NULL);
2225
2591
        goto cleanup;
2226
2592
    }
2227
2593
    ret = virNetworkObjIsActive(obj);
2242
2608
    obj = virNetworkFindByUUID(&driver->networks, net->uuid);
2243
2609
    networkDriverUnlock(driver);
2244
2610
    if (!obj) {
2245
 
        networkReportError(VIR_ERR_NO_NETWORK, NULL);
 
2611
        virReportError(VIR_ERR_NO_NETWORK, NULL);
2246
2612
        goto cleanup;
2247
2613
    }
2248
2614
    ret = obj->persistent;
2254
2620
}
2255
2621
 
2256
2622
 
 
2623
static int
 
2624
networkValidate(virNetworkDefPtr def)
 
2625
{
 
2626
    int ii;
 
2627
    bool vlanUsed, vlanAllowed, badVlanUse = false;
 
2628
    virPortGroupDefPtr defaultPortGroup = NULL;
 
2629
 
 
2630
    /* The only type of networks that currently support transparent
 
2631
     * vlan configuration are those using hostdev sr-iov devices from
 
2632
     * a pool, and those using an Open vSwitch bridge.
 
2633
     */
 
2634
 
 
2635
    vlanAllowed = (def->forwardType == VIR_NETWORK_FORWARD_BRIDGE &&
 
2636
                   def->virtPortProfile &&
 
2637
                   def->virtPortProfile->virtPortType == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH);
 
2638
 
 
2639
    vlanUsed = def->vlan.nTags > 0;
 
2640
    for (ii = 0; ii < def->nPortGroups; ii++) {
 
2641
        if (vlanUsed || def->portGroups[ii].vlan.nTags > 0) {
 
2642
            /* anyone using this portgroup will get a vlan tag. Verify
 
2643
             * that they will also be using an openvswitch connection,
 
2644
             * as that is the only type of network that currently
 
2645
             * supports a vlan tag.
 
2646
             */
 
2647
            if (def->portGroups[ii].virtPortProfile) {
 
2648
                if (def->forwardType != VIR_NETWORK_FORWARD_BRIDGE ||
 
2649
                    def->portGroups[ii].virtPortProfile->virtPortType
 
2650
                    != VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH) {
 
2651
                    badVlanUse = true;
 
2652
                }
 
2653
            } else if (!vlanAllowed) {
 
2654
                /* virtualport taken from base network definition */
 
2655
                badVlanUse = true;
 
2656
            }
 
2657
        }
 
2658
        if (def->portGroups[ii].isDefault) {
 
2659
            if (defaultPortGroup) {
 
2660
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
 
2661
                               _("network '%s' has multiple default "
 
2662
                                 "<portgroup> elements (%s and %s), "
 
2663
                                 "but only one default is allowed"),
 
2664
                               def->name, defaultPortGroup->name,
 
2665
                               def->portGroups[ii].name);
 
2666
                return -1;
 
2667
            }
 
2668
            defaultPortGroup = &def->portGroups[ii];
 
2669
        }
 
2670
    }
 
2671
    if (badVlanUse ||
 
2672
        (vlanUsed && !vlanAllowed && !defaultPortGroup)) {
 
2673
        /* NB: if defaultPortGroup is set, we don't directly look at
 
2674
         * vlanUsed && !vlanAllowed, because the network will never be
 
2675
         * used without having a portgroup added in, so all necessary
 
2676
         * checks were done in the loop above.
 
2677
         */
 
2678
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
 
2679
                       _("<vlan> element specified for network %s, "
 
2680
                         "whose type doesn't support vlan configuration"),
 
2681
                       def->name);
 
2682
        return -1;
 
2683
    }
 
2684
    return 0;
 
2685
}
 
2686
 
2257
2687
static virNetworkPtr networkCreate(virConnectPtr conn, const char *xml) {
2258
2688
    struct network_driver *driver = conn->networkPrivateData;
2259
2689
    virNetworkDefPtr def;
2281
2711
        virNetworkSetBridgeMacAddr(def);
2282
2712
    }
2283
2713
 
2284
 
    if (!(network = virNetworkAssignDef(&driver->networks,
2285
 
                                        def)))
 
2714
    if (networkValidate(def) < 0)
 
2715
       goto cleanup;
 
2716
 
 
2717
    /* NB: "live" is false because this transient network hasn't yet
 
2718
     * been started
 
2719
     */
 
2720
    if (!(network = virNetworkAssignDef(&driver->networks, def, false)))
2286
2721
        goto cleanup;
2287
2722
    def = NULL;
2288
2723
 
2342
2777
        if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET)) {
2343
2778
            if (ipdef->nranges || ipdef->nhosts) {
2344
2779
                if (ipv4def) {
2345
 
                    networkReportError(VIR_ERR_CONFIG_UNSUPPORTED,
2346
 
                                       "%s", _("Multiple dhcp sections found. dhcp is supported only for a single IPv4 address on each network"));
 
2780
                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
 
2781
                                   _("Multiple dhcp sections found. "
 
2782
                                     "dhcp is supported only for a "
 
2783
                                     "single IPv4 address on each network"));
2347
2784
                    goto cleanup;
2348
2785
                } else {
2349
2786
                    ipv4def = ipdef;
2352
2789
        }
2353
2790
    }
2354
2791
 
2355
 
    if (!(network = virNetworkAssignDef(&driver->networks,
2356
 
                                        def)))
 
2792
    if (networkValidate(def) < 0)
 
2793
       goto cleanup;
 
2794
 
 
2795
    if (!(network = virNetworkAssignDef(&driver->networks, def, false)))
2357
2796
        goto cleanup;
2358
2797
    freeDef = false;
2359
2798
 
2397
2836
 
2398
2837
    network = virNetworkFindByUUID(&driver->networks, net->uuid);
2399
2838
    if (!network) {
2400
 
        networkReportError(VIR_ERR_NO_NETWORK,
2401
 
                           "%s", _("no network with matching uuid"));
 
2839
        virReportError(VIR_ERR_NO_NETWORK,
 
2840
                       "%s", _("no network with matching uuid"));
2402
2841
        goto cleanup;
2403
2842
    }
2404
2843
 
2405
2844
    if (virNetworkObjIsActive(network)) {
2406
 
        networkReportError(VIR_ERR_OPERATION_INVALID,
2407
 
                           "%s", _("network is still active"));
 
2845
        virReportError(VIR_ERR_OPERATION_INVALID,
 
2846
                       "%s", _("network is still active"));
2408
2847
        goto cleanup;
2409
2848
    }
2410
2849
 
2475
2914
    return ret;
2476
2915
}
2477
2916
 
 
2917
static int
 
2918
networkUpdate(virNetworkPtr net,
 
2919
              unsigned int command,
 
2920
              unsigned int section,
 
2921
              int parentIndex,
 
2922
              const char *xml,
 
2923
              unsigned int flags)
 
2924
{
 
2925
    struct network_driver *driver = net->conn->networkPrivateData;
 
2926
    virNetworkObjPtr network = NULL;
 
2927
    int isActive, ret = -1, ii;
 
2928
    virNetworkIpDefPtr ipdef;
 
2929
    bool oldDhcpActive = false;
 
2930
 
 
2931
 
 
2932
    virCheckFlags(VIR_NETWORK_UPDATE_AFFECT_LIVE |
 
2933
                  VIR_NETWORK_UPDATE_AFFECT_CONFIG,
 
2934
                  -1);
 
2935
 
 
2936
    networkDriverLock(driver);
 
2937
 
 
2938
    network = virNetworkFindByUUID(&driver->networks, net->uuid);
 
2939
    if (!network) {
 
2940
        virReportError(VIR_ERR_NO_NETWORK,
 
2941
                       "%s", _("no network with matching uuid"));
 
2942
        goto cleanup;
 
2943
    }
 
2944
 
 
2945
    /* see if we are listening for dhcp pre-modification */
 
2946
    for (ii = 0;
 
2947
         (ipdef = virNetworkDefGetIpByIndex(network->def, AF_INET, ii));
 
2948
         ii++) {
 
2949
        if (ipdef->nranges || ipdef->nhosts) {
 
2950
            oldDhcpActive = true;
 
2951
            break;
 
2952
        }
 
2953
    }
 
2954
 
 
2955
    /* VIR_NETWORK_UPDATE_AFFECT_CURRENT means "change LIVE if network
 
2956
     * is active, else change CONFIG
 
2957
    */
 
2958
    isActive = virNetworkObjIsActive(network);
 
2959
    if ((flags & (VIR_NETWORK_UPDATE_AFFECT_LIVE |
 
2960
                  VIR_NETWORK_UPDATE_AFFECT_CONFIG)) ==
 
2961
        VIR_NETWORK_UPDATE_AFFECT_CURRENT) {
 
2962
        if (isActive)
 
2963
            flags |= VIR_NETWORK_UPDATE_AFFECT_LIVE;
 
2964
        else
 
2965
            flags |= VIR_NETWORK_UPDATE_AFFECT_CONFIG;
 
2966
    }
 
2967
 
 
2968
    /* update the network config in memory/on disk */
 
2969
    if (virNetworkObjUpdate(network, command, section, parentIndex, xml, flags) < 0)
 
2970
        goto cleanup;
 
2971
 
 
2972
    if (flags & VIR_NETWORK_UPDATE_AFFECT_CONFIG) {
 
2973
        /* save updated persistent config to disk */
 
2974
        if (virNetworkSaveConfig(driver->networkConfigDir,
 
2975
                                 virNetworkObjGetPersistentDef(network)) < 0) {
 
2976
            goto cleanup;
 
2977
        }
 
2978
    }
 
2979
 
 
2980
    if (isActive && (flags & VIR_NETWORK_UPDATE_AFFECT_LIVE)) {
 
2981
        /* rewrite dnsmasq host files, restart dnsmasq, update iptables
 
2982
         * rules, etc, according to which section was modified. Note that
 
2983
         * some sections require multiple actions, so a single switch
 
2984
         * statement is inadequate.
 
2985
         */
 
2986
        if (section == VIR_NETWORK_SECTION_BRIDGE ||
 
2987
            section == VIR_NETWORK_SECTION_DOMAIN ||
 
2988
            section == VIR_NETWORK_SECTION_IP ||
 
2989
            section == VIR_NETWORK_SECTION_IP_DHCP_RANGE) {
 
2990
            /* these sections all change things on the dnsmasq commandline,
 
2991
             * so we need to kill and restart dnsmasq.
 
2992
             */
 
2993
            if (networkRestartDhcpDaemon(network) < 0)
 
2994
                goto cleanup;
 
2995
 
 
2996
        } else if (section == VIR_NETWORK_SECTION_IP_DHCP_HOST) {
 
2997
            /* if we previously weren't listening for dhcp and now we
 
2998
             * are (or vice-versa) then we need to do a restart,
 
2999
             * otherwise we just need to do a refresh (redo the config
 
3000
             * files and send SIGHUP)
 
3001
             */
 
3002
            bool newDhcpActive = false;
 
3003
 
 
3004
            for (ii = 0;
 
3005
                 (ipdef = virNetworkDefGetIpByIndex(network->def, AF_INET, ii));
 
3006
                 ii++) {
 
3007
                if (ipdef->nranges || ipdef->nhosts) {
 
3008
                    newDhcpActive = true;
 
3009
                    break;
 
3010
                }
 
3011
            }
 
3012
 
 
3013
            if ((newDhcpActive != oldDhcpActive &&
 
3014
                networkRestartDhcpDaemon(network) < 0) ||
 
3015
                networkRefreshDhcpDaemon(network) < 0) {
 
3016
                goto cleanup;
 
3017
            }
 
3018
 
 
3019
        } else if (section == VIR_NETWORK_SECTION_DNS_HOST ||
 
3020
                   section == VIR_NETWORK_SECTION_DNS_TXT ||
 
3021
                   section == VIR_NETWORK_SECTION_DNS_SRV) {
 
3022
            /* these sections only change things in config files, so we
 
3023
             * can just update the config files and send SIGHUP to
 
3024
             * dnsmasq.
 
3025
             */
 
3026
            if (networkRefreshDhcpDaemon(network) < 0)
 
3027
                goto cleanup;
 
3028
 
 
3029
        }
 
3030
 
 
3031
        if (section == VIR_NETWORK_SECTION_IP) {
 
3032
            /* only a change in IP addresses will affect radvd, and all of radvd's
 
3033
             * config is stored in the conf file which will be re-read with a SIGHUP.
 
3034
             */
 
3035
            if (networkRefreshRadvd(network) < 0)
 
3036
                goto cleanup;
 
3037
        }
 
3038
 
 
3039
        if ((section == VIR_NETWORK_SECTION_IP ||
 
3040
             section == VIR_NETWORK_SECTION_FORWARD ||
 
3041
             section == VIR_NETWORK_SECTION_FORWARD_INTERFACE) &&
 
3042
           (network->def->forwardType == VIR_NETWORK_FORWARD_NONE ||
 
3043
            network->def->forwardType == VIR_NETWORK_FORWARD_NAT ||
 
3044
            network->def->forwardType == VIR_NETWORK_FORWARD_ROUTE)) {
 
3045
            /* these could affect the iptables rules */
 
3046
            networkRemoveIptablesRules(driver, network);
 
3047
            if (networkAddIptablesRules(driver, network) < 0)
 
3048
                goto cleanup;
 
3049
 
 
3050
        }
 
3051
 
 
3052
        /* save current network state to disk */
 
3053
        if ((ret = virNetworkSaveStatus(NETWORK_STATE_DIR, network)) < 0)
 
3054
            goto cleanup;
 
3055
    }
 
3056
    ret = 0;
 
3057
cleanup:
 
3058
    if (network)
 
3059
        virNetworkObjUnlock(network);
 
3060
    networkDriverUnlock(driver);
 
3061
    return ret;
 
3062
}
 
3063
 
2478
3064
static int networkStart(virNetworkPtr net) {
2479
3065
    struct network_driver *driver = net->conn->networkPrivateData;
2480
3066
    virNetworkObjPtr network;
2484
3070
    network = virNetworkFindByUUID(&driver->networks, net->uuid);
2485
3071
 
2486
3072
    if (!network) {
2487
 
        networkReportError(VIR_ERR_NO_NETWORK,
2488
 
                           "%s", _("no network with matching uuid"));
 
3073
        virReportError(VIR_ERR_NO_NETWORK,
 
3074
                       "%s", _("no network with matching uuid"));
2489
3075
        goto cleanup;
2490
3076
    }
2491
3077
 
2507
3093
    network = virNetworkFindByUUID(&driver->networks, net->uuid);
2508
3094
 
2509
3095
    if (!network) {
2510
 
        networkReportError(VIR_ERR_NO_NETWORK,
2511
 
                           "%s", _("no network with matching uuid"));
 
3096
        virReportError(VIR_ERR_NO_NETWORK,
 
3097
                       "%s", _("no network with matching uuid"));
2512
3098
        goto cleanup;
2513
3099
    }
2514
3100
 
2515
3101
    if (!virNetworkObjIsActive(network)) {
2516
 
        networkReportError(VIR_ERR_OPERATION_INVALID,
2517
 
                           "%s", _("network is not active"));
 
3102
        virReportError(VIR_ERR_OPERATION_INVALID,
 
3103
                       "%s", _("network is not active"));
2518
3104
        goto cleanup;
2519
3105
    }
2520
3106
 
2547
3133
    networkDriverUnlock(driver);
2548
3134
 
2549
3135
    if (!network) {
2550
 
        networkReportError(VIR_ERR_NO_NETWORK,
2551
 
                           "%s", _("no network with matching uuid"));
 
3136
        virReportError(VIR_ERR_NO_NETWORK,
 
3137
                       "%s", _("no network with matching uuid"));
2552
3138
        goto cleanup;
2553
3139
    }
2554
3140
 
2575
3161
    networkDriverUnlock(driver);
2576
3162
 
2577
3163
    if (!network) {
2578
 
        networkReportError(VIR_ERR_NO_NETWORK,
2579
 
                           "%s", _("no network with matching id"));
 
3164
        virReportError(VIR_ERR_NO_NETWORK,
 
3165
                       "%s", _("no network with matching id"));
2580
3166
        goto cleanup;
2581
3167
    }
2582
3168
 
2583
3169
    if (!(network->def->bridge)) {
2584
 
        networkReportError(VIR_ERR_INTERNAL_ERROR,
2585
 
                           _("network '%s' does not have a bridge name."),
2586
 
                           network->def->name);
 
3170
        virReportError(VIR_ERR_INTERNAL_ERROR,
 
3171
                       _("network '%s' does not have a bridge name."),
 
3172
                       network->def->name);
2587
3173
        goto cleanup;
2588
3174
    }
2589
3175
 
2607
3193
    network = virNetworkFindByUUID(&driver->networks, net->uuid);
2608
3194
    networkDriverUnlock(driver);
2609
3195
    if (!network) {
2610
 
        networkReportError(VIR_ERR_NO_NETWORK,
2611
 
                           "%s", _("no network with matching uuid"));
 
3196
        virReportError(VIR_ERR_NO_NETWORK,
 
3197
                       "%s", _("no network with matching uuid"));
2612
3198
        goto cleanup;
2613
3199
    }
2614
3200
 
2632
3218
    network = virNetworkFindByUUID(&driver->networks, net->uuid);
2633
3219
 
2634
3220
    if (!network) {
2635
 
        networkReportError(VIR_ERR_NO_NETWORK,
2636
 
                           "%s", _("no network with matching uuid"));
 
3221
        virReportError(VIR_ERR_NO_NETWORK,
 
3222
                       "%s", _("no network with matching uuid"));
2637
3223
        goto cleanup;
2638
3224
    }
2639
3225
 
2640
3226
    if (!network->persistent) {
2641
 
        networkReportError(VIR_ERR_OPERATION_INVALID,
2642
 
                           "%s", _("cannot set autostart for transient network"));
 
3227
        virReportError(VIR_ERR_OPERATION_INVALID,
 
3228
                       "%s", _("cannot set autostart for transient network"));
2643
3229
        goto cleanup;
2644
3230
    }
2645
3231
 
2696
3282
    .listNetworks = networkListNetworks, /* 0.2.0 */
2697
3283
    .numOfDefinedNetworks = networkNumDefinedNetworks, /* 0.2.0 */
2698
3284
    .listDefinedNetworks = networkListDefinedNetworks, /* 0.2.0 */
 
3285
    .listAllNetworks = networkListAllNetworks, /* 0.10.2 */
2699
3286
    .networkLookupByUUID = networkLookupByUUID, /* 0.2.0 */
2700
3287
    .networkLookupByName = networkLookupByName, /* 0.2.0 */
2701
3288
    .networkCreateXML = networkCreate, /* 0.2.0 */
2702
3289
    .networkDefineXML = networkDefine, /* 0.2.0 */
2703
3290
    .networkUndefine = networkUndefine, /* 0.2.0 */
 
3291
    .networkUpdate = networkUpdate, /* 0.10.2 */
2704
3292
    .networkCreate = networkStart, /* 0.2.0 */
2705
3293
    .networkDestroy = networkDestroy, /* 0.2.0 */
2706
3294
    .networkGetXMLDesc = networkGetXMLDesc, /* 0.2.0 */
2735
3323
 * "backend" function table.
2736
3324
 */
2737
3325
 
 
3326
/* networkCreateInterfacePool:
 
3327
 * @netdef: the original NetDef from the network
 
3328
 *
 
3329
 * Creates an implicit interface pool of VF's when a PF dev is given
 
3330
 */
 
3331
static int
 
3332
networkCreateInterfacePool(virNetworkDefPtr netdef) {
 
3333
    unsigned int num_virt_fns = 0;
 
3334
    char **vfname = NULL;
 
3335
    struct pci_config_address **virt_fns;
 
3336
    int ret = -1, ii = 0;
 
3337
 
 
3338
    if ((virNetDevGetVirtualFunctions(netdef->forwardPfs->dev,
 
3339
                                      &vfname, &virt_fns, &num_virt_fns)) < 0) {
 
3340
        virReportError(VIR_ERR_INTERNAL_ERROR,
 
3341
                       _("Could not get Virtual functions on %s"),
 
3342
                       netdef->forwardPfs->dev);
 
3343
        goto finish;
 
3344
    }
 
3345
 
 
3346
    if (num_virt_fns == 0) {
 
3347
        virReportError(VIR_ERR_INTERNAL_ERROR,
 
3348
                       _("No Vf's present on SRIOV PF %s"),
 
3349
                       netdef->forwardPfs->dev);
 
3350
       goto finish;
 
3351
    }
 
3352
 
 
3353
    if ((VIR_ALLOC_N(netdef->forwardIfs, num_virt_fns)) < 0) {
 
3354
        virReportOOMError();
 
3355
        goto finish;
 
3356
    }
 
3357
 
 
3358
    netdef->nForwardIfs = num_virt_fns;
 
3359
 
 
3360
    for (ii = 0; ii < netdef->nForwardIfs; ii++) {
 
3361
        if ((netdef->forwardType == VIR_NETWORK_FORWARD_BRIDGE) ||
 
3362
            (netdef->forwardType == VIR_NETWORK_FORWARD_PRIVATE) ||
 
3363
            (netdef->forwardType == VIR_NETWORK_FORWARD_VEPA) ||
 
3364
            (netdef->forwardType == VIR_NETWORK_FORWARD_PASSTHROUGH)) {
 
3365
            netdef->forwardIfs[ii].type = VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_NETDEV;
 
3366
            if(vfname[ii]) {
 
3367
                netdef->forwardIfs[ii].device.dev = strdup(vfname[ii]);
 
3368
                if (!netdef->forwardIfs[ii].device.dev) {
 
3369
                    virReportOOMError();
 
3370
                    goto finish;
 
3371
                }
 
3372
            }
 
3373
            else {
 
3374
                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
 
3375
                               _("Direct mode types require interface names"));
 
3376
                goto finish;
 
3377
            }
 
3378
        }
 
3379
        else if (netdef->forwardType == VIR_NETWORK_FORWARD_HOSTDEV) {
 
3380
            /* VF's are always PCI devices */
 
3381
            netdef->forwardIfs[ii].type = VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_PCI;
 
3382
            netdef->forwardIfs[ii].device.pci.domain = virt_fns[ii]->domain;
 
3383
            netdef->forwardIfs[ii].device.pci.bus = virt_fns[ii]->bus;
 
3384
            netdef->forwardIfs[ii].device.pci.slot = virt_fns[ii]->slot;
 
3385
            netdef->forwardIfs[ii].device.pci.function = virt_fns[ii]->function;
 
3386
        }
 
3387
    }
 
3388
 
 
3389
    ret = 0;
 
3390
finish:
 
3391
    for (ii = 0; ii < num_virt_fns; ii++) {
 
3392
        VIR_FREE(vfname[ii]);
 
3393
        VIR_FREE(virt_fns[ii]);
 
3394
    }
 
3395
    VIR_FREE(vfname);
 
3396
    VIR_FREE(virt_fns);
 
3397
    return ret;
 
3398
}
 
3399
 
2738
3400
/* networkAllocateActualDevice:
2739
3401
 * @iface: the original NetDef from the domain
2740
3402
 *
2750
3412
networkAllocateActualDevice(virDomainNetDefPtr iface)
2751
3413
{
2752
3414
    struct network_driver *driver = driverState;
2753
 
    virNetworkObjPtr network;
2754
 
    virNetworkDefPtr netdef;
2755
 
    virPortGroupDefPtr portgroup;
2756
 
    unsigned int num_virt_fns = 0;
2757
 
    char **vfname = NULL;
 
3415
    enum virDomainNetType actualType = iface->type;
 
3416
    virNetworkObjPtr network = NULL;
 
3417
    virNetworkDefPtr netdef = NULL;
 
3418
    virPortGroupDefPtr portgroup = NULL;
 
3419
    virNetDevVPortProfilePtr virtport = iface->virtPortProfile;
 
3420
    virNetDevVlanPtr vlan = NULL;
 
3421
    virNetworkForwardIfDefPtr dev = NULL;
2758
3422
    int ii;
2759
3423
    int ret = -1;
2760
3424
 
 
3425
    /* it's handy to have this initialized if we skip directly to validate */
 
3426
    if (iface->vlan.nTags > 0)
 
3427
        vlan = &iface->vlan;
 
3428
 
2761
3429
    if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK)
2762
 
        return 0;
 
3430
        goto validate;
2763
3431
 
2764
3432
    virDomainActualNetDefFree(iface->data.network.actual);
2765
3433
    iface->data.network.actual = NULL;
2768
3436
    network = virNetworkFindByName(&driver->networks, iface->data.network.name);
2769
3437
    networkDriverUnlock(driver);
2770
3438
    if (!network) {
2771
 
        networkReportError(VIR_ERR_NO_NETWORK,
2772
 
                           _("no network with matching name '%s'"),
2773
 
                           iface->data.network.name);
2774
 
        goto cleanup;
 
3439
        virReportError(VIR_ERR_NO_NETWORK,
 
3440
                       _("no network with matching name '%s'"),
 
3441
                       iface->data.network.name);
 
3442
        goto error;
2775
3443
    }
2776
 
 
2777
3444
    netdef = network->def;
2778
3445
 
2779
3446
    /* portgroup can be present for any type of network, in particular
2790
3457
        if (!iface->data.network.actual
2791
3458
            && (VIR_ALLOC(iface->data.network.actual) < 0)) {
2792
3459
            virReportOOMError();
2793
 
            goto cleanup;
 
3460
            goto error;
2794
3461
        }
2795
3462
 
2796
3463
        if (virNetDevBandwidthCopy(&iface->data.network.actual->bandwidth,
2797
3464
                                   portgroup->bandwidth) < 0)
2798
 
            goto cleanup;
 
3465
            goto error;
2799
3466
    }
2800
3467
 
2801
3468
    if ((netdef->forwardType == VIR_NETWORK_FORWARD_NONE) ||
2817
3484
        if (!iface->data.network.actual
2818
3485
            && (VIR_ALLOC(iface->data.network.actual) < 0)) {
2819
3486
            virReportOOMError();
2820
 
            goto cleanup;
 
3487
            goto error;
2821
3488
        }
2822
3489
 
2823
 
        iface->data.network.actual->type = VIR_DOMAIN_NET_TYPE_BRIDGE;
 
3490
        iface->data.network.actual->type = actualType = VIR_DOMAIN_NET_TYPE_BRIDGE;
2824
3491
        iface->data.network.actual->data.bridge.brname = strdup(netdef->bridge);
2825
3492
        if (!iface->data.network.actual->data.bridge.brname) {
2826
3493
            virReportOOMError();
2827
 
            goto cleanup;
 
3494
            goto error;
 
3495
        }
 
3496
 
 
3497
        /* merge virtualports from interface, network, and portgroup to
 
3498
         * arrive at actual virtualport to use
 
3499
         */
 
3500
        if (virNetDevVPortProfileMerge3(&iface->data.network.actual->virtPortProfile,
 
3501
                                        iface->virtPortProfile,
 
3502
                                        netdef->virtPortProfile,
 
3503
                                        portgroup
 
3504
                                        ? portgroup->virtPortProfile : NULL) < 0) {
 
3505
            goto error;
 
3506
        }
 
3507
        virtport = iface->data.network.actual->virtPortProfile;
 
3508
        if (virtport) {
 
3509
            /* only type='openvswitch' is allowed for bridges */
 
3510
            if (virtport->virtPortType != VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH) {
 
3511
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
 
3512
                               _("<virtualport type='%s'> not supported for network "
 
3513
                                 "'%s' which uses a bridge device"),
 
3514
                               virNetDevVPortTypeToString(virtport->virtPortType),
 
3515
                               netdef->name);
 
3516
                goto error;
 
3517
            }
 
3518
        }
 
3519
 
 
3520
    } else if (netdef->forwardType == VIR_NETWORK_FORWARD_HOSTDEV) {
 
3521
 
 
3522
        if (!iface->data.network.actual
 
3523
            && (VIR_ALLOC(iface->data.network.actual) < 0)) {
 
3524
            virReportOOMError();
 
3525
            goto error;
 
3526
        }
 
3527
 
 
3528
        iface->data.network.actual->type = actualType = VIR_DOMAIN_NET_TYPE_HOSTDEV;
 
3529
        if (netdef->nForwardPfs > 0 && netdef->nForwardIfs <= 0 &&
 
3530
            networkCreateInterfacePool(netdef) < 0) {
 
3531
            goto error;
 
3532
        }
 
3533
 
 
3534
        /* pick first dev with 0 connections */
 
3535
        for (ii = 0; ii < netdef->nForwardIfs; ii++) {
 
3536
            if (netdef->forwardIfs[ii].connections == 0) {
 
3537
                dev = &netdef->forwardIfs[ii];
 
3538
                break;
 
3539
            }
 
3540
        }
 
3541
        if (!dev) {
 
3542
            virReportError(VIR_ERR_INTERNAL_ERROR,
 
3543
                           _("network '%s' requires exclusive access "
 
3544
                             "to interfaces, but none are available"),
 
3545
                           netdef->name);
 
3546
            goto error;
 
3547
        }
 
3548
        iface->data.network.actual->data.hostdev.def.parent.type = VIR_DOMAIN_DEVICE_NET;
 
3549
        iface->data.network.actual->data.hostdev.def.parent.data.net = iface;
 
3550
        iface->data.network.actual->data.hostdev.def.info = &iface->info;
 
3551
        iface->data.network.actual->data.hostdev.def.mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
 
3552
        iface->data.network.actual->data.hostdev.def.managed = netdef->managed;
 
3553
        iface->data.network.actual->data.hostdev.def.source.subsys.type = dev->type;
 
3554
        iface->data.network.actual->data.hostdev.def.source.subsys.u.pci = dev->device.pci;
 
3555
 
 
3556
        /* merge virtualports from interface, network, and portgroup to
 
3557
         * arrive at actual virtualport to use
 
3558
         */
 
3559
        if (virNetDevVPortProfileMerge3(&iface->data.network.actual->virtPortProfile,
 
3560
                                        iface->virtPortProfile,
 
3561
                                        netdef->virtPortProfile,
 
3562
                                        portgroup
 
3563
                                        ? portgroup->virtPortProfile : NULL) < 0) {
 
3564
            goto error;
 
3565
        }
 
3566
        virtport = iface->data.network.actual->virtPortProfile;
 
3567
        if (virtport) {
 
3568
            /* make sure type is supported for hostdev connections */
 
3569
            if (virtport->virtPortType != VIR_NETDEV_VPORT_PROFILE_8021QBG &&
 
3570
                virtport->virtPortType != VIR_NETDEV_VPORT_PROFILE_8021QBH) {
 
3571
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
 
3572
                               _("<virtualport type='%s'> not supported for network "
 
3573
                                 "'%s' which uses an SR-IOV Virtual Function "
 
3574
                                 "via PCI passthrough"),
 
3575
                               virNetDevVPortTypeToString(virtport->virtPortType),
 
3576
                               netdef->name);
 
3577
                goto error;
 
3578
            }
2828
3579
        }
2829
3580
 
2830
3581
    } else if ((netdef->forwardType == VIR_NETWORK_FORWARD_BRIDGE) ||
2831
3582
               (netdef->forwardType == VIR_NETWORK_FORWARD_PRIVATE) ||
2832
3583
               (netdef->forwardType == VIR_NETWORK_FORWARD_VEPA) ||
2833
3584
               (netdef->forwardType == VIR_NETWORK_FORWARD_PASSTHROUGH)) {
2834
 
        virNetDevVPortProfilePtr virtport = NULL;
2835
3585
 
2836
3586
        /* <forward type='bridge|private|vepa|passthrough'> are all
2837
3587
         * VIR_DOMAIN_NET_TYPE_DIRECT.
2840
3590
        if (!iface->data.network.actual
2841
3591
            && (VIR_ALLOC(iface->data.network.actual) < 0)) {
2842
3592
            virReportOOMError();
2843
 
            goto cleanup;
 
3593
            goto error;
2844
3594
        }
2845
3595
 
2846
3596
        /* Set type=direct and appropriate <source mode='xxx'/> */
2847
 
        iface->data.network.actual->type = VIR_DOMAIN_NET_TYPE_DIRECT;
 
3597
        iface->data.network.actual->type = actualType = VIR_DOMAIN_NET_TYPE_DIRECT;
2848
3598
        switch (netdef->forwardType) {
2849
3599
        case VIR_NETWORK_FORWARD_BRIDGE:
2850
3600
            iface->data.network.actual->data.direct.mode = VIR_NETDEV_MACVLAN_MODE_BRIDGE;
2860
3610
            break;
2861
3611
        }
2862
3612
 
2863
 
        /* Find the most specific virtportprofile and copy it */
2864
 
        if (iface->data.network.virtPortProfile) {
2865
 
            virtport = iface->data.network.virtPortProfile;
2866
 
        } else {
2867
 
            if (portgroup)
2868
 
                virtport = portgroup->virtPortProfile;
2869
 
            else
2870
 
                virtport = netdef->virtPortProfile;
 
3613
        /* merge virtualports from interface, network, and portgroup to
 
3614
         * arrive at actual virtualport to use
 
3615
         */
 
3616
        if (virNetDevVPortProfileMerge3(&iface->data.network.actual->virtPortProfile,
 
3617
                                        iface->virtPortProfile,
 
3618
                                        netdef->virtPortProfile,
 
3619
                                        portgroup
 
3620
                                        ? portgroup->virtPortProfile : NULL) < 0) {
 
3621
            goto error;
2871
3622
        }
 
3623
        virtport = iface->data.network.actual->virtPortProfile;
2872
3624
        if (virtport) {
2873
 
            if (VIR_ALLOC(iface->data.network.actual->data.direct.virtPortProfile) < 0) {
2874
 
                virReportOOMError();
2875
 
                goto cleanup;
 
3625
            /* make sure type is supported for macvtap connections */
 
3626
            if (virtport->virtPortType != VIR_NETDEV_VPORT_PROFILE_8021QBG &&
 
3627
                virtport->virtPortType != VIR_NETDEV_VPORT_PROFILE_8021QBH) {
 
3628
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
 
3629
                               _("<virtualport type='%s'> not supported for network "
 
3630
                                 "'%s' which uses a macvtap device"),
 
3631
                               virNetDevVPortTypeToString(virtport->virtPortType),
 
3632
                               netdef->name);
 
3633
                goto error;
2876
3634
            }
2877
 
            /* There are no pointers in a virtualPortProfile, so a shallow copy
2878
 
             * is sufficient
2879
 
             */
2880
 
            *iface->data.network.actual->data.direct.virtPortProfile = *virtport;
2881
3635
        }
2882
3636
 
2883
3637
        /* If there is only a single device, just return it (caller will detect
2884
3638
         * any error if exclusive use is required but could not be acquired).
2885
3639
         */
2886
3640
        if ((netdef->nForwardIfs <= 0) && (netdef->nForwardPfs <= 0)) {
2887
 
            networkReportError(VIR_ERR_INTERNAL_ERROR,
2888
 
                               _("network '%s' uses a direct mode, but has no forward dev and no interface pool"),
2889
 
                               netdef->name);
2890
 
            goto cleanup;
 
3641
            virReportError(VIR_ERR_INTERNAL_ERROR,
 
3642
                           _("network '%s' uses a direct mode, but "
 
3643
                             "has no forward dev and no interface pool"),
 
3644
                           netdef->name);
 
3645
            goto error;
2891
3646
        } else {
2892
 
            virNetworkForwardIfDefPtr dev = NULL;
2893
 
 
2894
3647
            /* pick an interface from the pool */
2895
3648
 
2896
 
            /* PASSTHROUGH mode, and PRIVATE Mode + 802.1Qbh both require
2897
 
             * exclusive access to a device, so current usageCount must be
2898
 
             * 0.  Other modes can share, so just search for the one with
2899
 
             * the lowest usageCount.
 
3649
            if (netdef->nForwardPfs > 0 && netdef->nForwardIfs == 0 &&
 
3650
                networkCreateInterfacePool(netdef) < 0) {
 
3651
                goto error;
 
3652
            }
 
3653
 
 
3654
            /* PASSTHROUGH mode, and PRIVATE Mode + 802.1Qbh both
 
3655
             * require exclusive access to a device, so current
 
3656
             * connections count must be 0.  Other modes can share, so
 
3657
             * just search for the one with the lowest number of
 
3658
             * connections.
2900
3659
             */
2901
 
            if (netdef->forwardType == VIR_NETWORK_FORWARD_PASSTHROUGH) {
2902
 
                if ((netdef->nForwardPfs > 0) && (netdef->nForwardIfs <= 0)) {
2903
 
                    if ((virNetDevGetVirtualFunctions(netdef->forwardPfs->dev,
2904
 
                                                      &vfname, &num_virt_fns)) < 0) {
2905
 
                        networkReportError(VIR_ERR_INTERNAL_ERROR,
2906
 
                                           _("Could not get Virtual functions on %s"),
2907
 
                                           netdef->forwardPfs->dev);
2908
 
                        goto cleanup;
2909
 
                    }
2910
 
 
2911
 
                    if (num_virt_fns == 0) {
2912
 
                        networkReportError(VIR_ERR_INTERNAL_ERROR,
2913
 
                                           _("No Vf's present on SRIOV PF %s"),
2914
 
                                           netdef->forwardPfs->dev);
2915
 
                        goto cleanup;
2916
 
                    }
2917
 
 
2918
 
                    if ((VIR_ALLOC_N(netdef->forwardIfs, num_virt_fns)) < 0) {
2919
 
                        virReportOOMError();
2920
 
                        goto cleanup;
2921
 
                    }
2922
 
 
2923
 
                    netdef->nForwardIfs = num_virt_fns;
2924
 
 
2925
 
                    for (ii = 0; ii < netdef->nForwardIfs; ii++) {
2926
 
                        netdef->forwardIfs[ii].dev = strdup(vfname[ii]);
2927
 
                        if (!netdef->forwardIfs[ii].dev) {
2928
 
                            virReportOOMError();
2929
 
                            goto cleanup;
2930
 
                        }
2931
 
                        netdef->forwardIfs[ii].usageCount = 0;
2932
 
                    }
2933
 
                }
2934
 
 
2935
 
                /* pick first dev with 0 usageCount */
2936
 
 
2937
 
                for (ii = 0; ii < netdef->nForwardIfs; ii++) {
2938
 
                    if (netdef->forwardIfs[ii].usageCount == 0) {
2939
 
                        dev = &netdef->forwardIfs[ii];
2940
 
                        break;
2941
 
                    }
2942
 
                }
2943
 
            } else if ((netdef->forwardType == VIR_NETWORK_FORWARD_PRIVATE) &&
2944
 
                       iface->data.network.actual->data.direct.virtPortProfile &&
2945
 
                       (iface->data.network.actual->data.direct.virtPortProfile->virtPortType
2946
 
                        == VIR_NETDEV_VPORT_PROFILE_8021QBH)) {
2947
 
 
2948
 
                /* pick first dev with 0 usageCount */
2949
 
                for (ii = 0; ii < netdef->nForwardIfs; ii++) {
2950
 
                    if (netdef->forwardIfs[ii].usageCount == 0) {
 
3660
            if ((netdef->forwardType == VIR_NETWORK_FORWARD_PASSTHROUGH) ||
 
3661
                ((netdef->forwardType == VIR_NETWORK_FORWARD_PRIVATE) &&
 
3662
                 iface->data.network.actual->virtPortProfile &&
 
3663
                 (iface->data.network.actual->virtPortProfile->virtPortType
 
3664
                  == VIR_NETDEV_VPORT_PROFILE_8021QBH))) {
 
3665
 
 
3666
                /* pick first dev with 0 connections */
 
3667
                for (ii = 0; ii < netdef->nForwardIfs; ii++) {
 
3668
                    if (netdef->forwardIfs[ii].connections == 0) {
2951
3669
                        dev = &netdef->forwardIfs[ii];
2952
3670
                        break;
2953
3671
                    }
2956
3674
                /* pick least used dev */
2957
3675
                dev = &netdef->forwardIfs[0];
2958
3676
                for (ii = 1; ii < netdef->nForwardIfs; ii++) {
2959
 
                    if (netdef->forwardIfs[ii].usageCount < dev->usageCount)
 
3677
                    if (netdef->forwardIfs[ii].connections < dev->connections)
2960
3678
                        dev = &netdef->forwardIfs[ii];
2961
3679
                }
2962
3680
            }
2963
3681
            /* dev points at the physical device we want to use */
2964
3682
            if (!dev) {
2965
 
                networkReportError(VIR_ERR_INTERNAL_ERROR,
2966
 
                                   _("network '%s' requires exclusive access to interfaces, but none are available"),
2967
 
                                   netdef->name);
2968
 
                goto cleanup;
 
3683
                virReportError(VIR_ERR_INTERNAL_ERROR,
 
3684
                               _("network '%s' requires exclusive access "
 
3685
                                 "to interfaces, but none are available"),
 
3686
                               netdef->name);
 
3687
                goto error;
2969
3688
            }
2970
 
            iface->data.network.actual->data.direct.linkdev = strdup(dev->dev);
 
3689
            iface->data.network.actual->data.direct.linkdev = strdup(dev->device.dev);
2971
3690
            if (!iface->data.network.actual->data.direct.linkdev) {
2972
3691
                virReportOOMError();
2973
 
                goto cleanup;
2974
 
            }
2975
 
            /* we are now assured of success, so mark the allocation */
2976
 
            dev->usageCount++;
2977
 
            VIR_DEBUG("Using physical device %s, usageCount %d",
2978
 
                      dev->dev, dev->usageCount);
2979
 
        }
2980
 
    }
2981
 
 
 
3692
                goto error;
 
3693
            }
 
3694
        }
 
3695
    }
 
3696
 
 
3697
    if (virNetDevVPortProfileCheckComplete(virtport, true) < 0)
 
3698
        goto error;
 
3699
 
 
3700
    /* copy appropriate vlan info to actualNet */
 
3701
    if (iface->vlan.nTags > 0)
 
3702
        vlan = &iface->vlan;
 
3703
    else if (portgroup && portgroup->vlan.nTags > 0)
 
3704
        vlan = &portgroup->vlan;
 
3705
    else if (netdef && netdef->vlan.nTags > 0)
 
3706
        vlan = &netdef->vlan;
 
3707
 
 
3708
    if (virNetDevVlanCopy(&iface->data.network.actual->vlan, vlan) < 0)
 
3709
        goto error;
 
3710
 
 
3711
validate:
 
3712
    /* make sure that everything now specified for the device is
 
3713
     * actually supported on this type of network. NB: network,
 
3714
     * netdev, and iface->data.network.actual may all be NULL.
 
3715
     */
 
3716
 
 
3717
    if (vlan) {
 
3718
        /* vlan configuration via libvirt is only supported for
 
3719
         * PCI Passthrough SR-IOV devices and openvswitch bridges.
 
3720
         * otherwise log an error and fail
 
3721
         */
 
3722
        if (!(actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV ||
 
3723
              (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE &&
 
3724
               virtport && virtport->virtPortType
 
3725
               == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH))) {
 
3726
            if (netdef) {
 
3727
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
 
3728
                               _("an interface connecting to network '%s' "
 
3729
                                 "is requesting a vlan tag, but that is not "
 
3730
                                 "supported for this type of network"),
 
3731
                               netdef->name);
 
3732
            } else {
 
3733
                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
 
3734
                               _("an interface of type '%s' "
 
3735
                                 "is requesting a vlan tag, but that is not "
 
3736
                                 "supported for this type of connection"),
 
3737
                               virDomainNetTypeToString(iface->type));
 
3738
            }
 
3739
            goto error;
 
3740
        }
 
3741
    }
 
3742
 
 
3743
    if (dev) {
 
3744
        /* we are now assured of success, so mark the allocation */
 
3745
        dev->connections++;
 
3746
        if (actualType != VIR_DOMAIN_NET_TYPE_HOSTDEV) {
 
3747
            VIR_DEBUG("Using physical device %s, %d connections",
 
3748
                      dev->device.dev, dev->connections);
 
3749
        } else {
 
3750
            VIR_DEBUG("Using physical device %04x:%02x:%02x.%x, connections %d",
 
3751
                      dev->device.pci.domain, dev->device.pci.bus,
 
3752
                      dev->device.pci.slot, dev->device.pci.function,
 
3753
                      dev->connections);
 
3754
        }
 
3755
    }
 
3756
 
 
3757
    if (netdef) {
 
3758
        netdef->connections++;
 
3759
        VIR_DEBUG("Using network %s, %d connections",
 
3760
                  netdef->name, netdef->connections);
 
3761
    }
2982
3762
    ret = 0;
 
3763
 
2983
3764
cleanup:
2984
 
    for (ii = 0; ii < num_virt_fns; ii++)
2985
 
        VIR_FREE(vfname[ii]);
2986
 
    VIR_FREE(vfname);
2987
3765
    if (network)
2988
3766
        virNetworkObjUnlock(network);
2989
 
    if (ret < 0) {
 
3767
    return ret;
 
3768
 
 
3769
error:
 
3770
    if (iface->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
2990
3771
        virDomainActualNetDefFree(iface->data.network.actual);
2991
3772
        iface->data.network.actual = NULL;
2992
3773
    }
2993
 
    return ret;
 
3774
    goto cleanup;
2994
3775
}
2995
3776
 
2996
3777
/* networkNotifyActualDevice:
3007
3788
networkNotifyActualDevice(virDomainNetDefPtr iface)
3008
3789
{
3009
3790
    struct network_driver *driver = driverState;
 
3791
    enum virDomainNetType actualType = virDomainNetGetActualType(iface);
3010
3792
    virNetworkObjPtr network;
3011
3793
    virNetworkDefPtr netdef;
3012
 
    const char *actualDev;
3013
 
    int ret = -1;
 
3794
    virNetworkForwardIfDefPtr dev = NULL;
 
3795
    int ii, ret = -1;
3014
3796
 
3015
3797
    if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK)
3016
3798
       return 0;
3017
3799
 
 
3800
    networkDriverLock(driver);
 
3801
    network = virNetworkFindByName(&driver->networks, iface->data.network.name);
 
3802
    networkDriverUnlock(driver);
 
3803
    if (!network) {
 
3804
        virReportError(VIR_ERR_NO_NETWORK,
 
3805
                       _("no network with matching name '%s'"),
 
3806
                       iface->data.network.name);
 
3807
        goto error;
 
3808
    }
 
3809
    netdef = network->def;
 
3810
 
3018
3811
    if (!iface->data.network.actual ||
3019
 
        (virDomainNetGetActualType(iface) != VIR_DOMAIN_NET_TYPE_DIRECT)) {
 
3812
        (actualType != VIR_DOMAIN_NET_TYPE_DIRECT &&
 
3813
         actualType != VIR_DOMAIN_NET_TYPE_HOSTDEV)) {
3020
3814
        VIR_DEBUG("Nothing to claim from network %s", iface->data.network.name);
3021
 
        return 0;
3022
 
    }
3023
 
 
3024
 
    networkDriverLock(driver);
3025
 
    network = virNetworkFindByName(&driver->networks, iface->data.network.name);
3026
 
    networkDriverUnlock(driver);
3027
 
    if (!network) {
3028
 
        networkReportError(VIR_ERR_NO_NETWORK,
3029
 
                           _("no network with matching name '%s'"),
3030
 
                           iface->data.network.name);
3031
 
        goto cleanup;
3032
 
    }
3033
 
 
3034
 
    actualDev = virDomainNetGetActualDirectDev(iface);
3035
 
    if (!actualDev) {
3036
 
        networkReportError(VIR_ERR_INTERNAL_ERROR,
3037
 
                           "%s", _("the interface uses a direct mode, but has no source dev"));
3038
 
        goto cleanup;
3039
 
    }
3040
 
 
3041
 
    netdef = network->def;
 
3815
        goto success;
 
3816
    }
 
3817
 
 
3818
    if (netdef->nForwardPfs > 0 && netdef->nForwardIfs == 0 &&
 
3819
        networkCreateInterfacePool(netdef) < 0) {
 
3820
        goto error;
 
3821
    }
3042
3822
    if (netdef->nForwardIfs == 0) {
3043
 
        networkReportError(VIR_ERR_INTERNAL_ERROR,
3044
 
                           _("network '%s' uses a direct mode, but has no forward dev and no interface pool"),
3045
 
                           netdef->name);
3046
 
        goto cleanup;
3047
 
    } else {
3048
 
        int ii;
3049
 
        virNetworkForwardIfDefPtr dev = NULL;
3050
 
 
3051
 
        /* find the matching interface in the pool and increment its usageCount */
3052
 
 
 
3823
        virReportError(VIR_ERR_INTERNAL_ERROR,
 
3824
                       _("network '%s' uses a direct or hostdev mode, "
 
3825
                         "but has no forward dev and no interface pool"),
 
3826
                       netdef->name);
 
3827
        goto error;
 
3828
    }
 
3829
 
 
3830
    if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
 
3831
        const char *actualDev;
 
3832
 
 
3833
        actualDev = virDomainNetGetActualDirectDev(iface);
 
3834
        if (!actualDev) {
 
3835
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
 
3836
                           _("the interface uses a direct mode, "
 
3837
                             "but has no source dev"));
 
3838
            goto error;
 
3839
        }
 
3840
 
 
3841
        /* find the matching interface and increment its connections */
3053
3842
        for (ii = 0; ii < netdef->nForwardIfs; ii++) {
3054
 
            if (STREQ(actualDev, netdef->forwardIfs[ii].dev)) {
 
3843
            if (netdef->forwardIfs[ii].type
 
3844
                == VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_NETDEV &&
 
3845
                STREQ(actualDev, netdef->forwardIfs[ii].device.dev)) {
3055
3846
                dev = &netdef->forwardIfs[ii];
3056
3847
                break;
3057
3848
            }
3058
3849
        }
3059
3850
        /* dev points at the physical device we want to use */
3060
3851
        if (!dev) {
3061
 
            networkReportError(VIR_ERR_INTERNAL_ERROR,
3062
 
                               _("network '%s' doesn't have dev='%s' in use by domain"),
3063
 
                               netdef->name, actualDev);
3064
 
            goto cleanup;
 
3852
            virReportError(VIR_ERR_INTERNAL_ERROR,
 
3853
                           _("network '%s' doesn't have dev='%s' "
 
3854
                             "in use by domain"),
 
3855
                           netdef->name, actualDev);
 
3856
            goto error;
3065
3857
        }
3066
3858
 
3067
 
        /* PASSTHROUGH mode, and PRIVATE Mode + 802.1Qbh both require
3068
 
         * exclusive access to a device, so current usageCount must be
3069
 
         * 0 in those cases.
 
3859
        /* PASSTHROUGH mode and PRIVATE Mode + 802.1Qbh both require
 
3860
         * exclusive access to a device, so current connections count
 
3861
         * must be 0 in those cases.
3070
3862
         */
3071
 
        if ((dev->usageCount > 0) &&
 
3863
        if ((dev->connections > 0) &&
3072
3864
            ((netdef->forwardType == VIR_NETWORK_FORWARD_PASSTHROUGH) ||
3073
3865
             ((netdef->forwardType == VIR_NETWORK_FORWARD_PRIVATE) &&
3074
 
              iface->data.network.actual->data.direct.virtPortProfile &&
3075
 
              (iface->data.network.actual->data.direct.virtPortProfile->virtPortType
 
3866
              iface->data.network.actual->virtPortProfile &&
 
3867
              (iface->data.network.actual->virtPortProfile->virtPortType
3076
3868
               == VIR_NETDEV_VPORT_PROFILE_8021QBH)))) {
3077
 
            networkReportError(VIR_ERR_INTERNAL_ERROR,
3078
 
                               _("network '%s' claims dev='%s' is already in use by a different domain"),
3079
 
                               netdef->name, actualDev);
3080
 
            goto cleanup;
3081
 
        }
3082
 
        /* we are now assured of success, so mark the allocation */
3083
 
        dev->usageCount++;
3084
 
        VIR_DEBUG("Using physical device %s, usageCount %d",
3085
 
                  dev->dev, dev->usageCount);
 
3869
            virReportError(VIR_ERR_INTERNAL_ERROR,
 
3870
                           _("network '%s' claims dev='%s' is already in "
 
3871
                             "use by a different domain"),
 
3872
                           netdef->name, actualDev);
 
3873
            goto error;
 
3874
        }
 
3875
 
 
3876
        /* we are now assured of success, so mark the allocation */
 
3877
        dev->connections++;
 
3878
        VIR_DEBUG("Using physical device %s, connections %d",
 
3879
                  dev->device.dev, dev->connections);
 
3880
 
 
3881
    }  else /* if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) */ {
 
3882
        virDomainHostdevDefPtr hostdev;
 
3883
 
 
3884
        hostdev = virDomainNetGetActualHostdev(iface);
 
3885
        if (!hostdev) {
 
3886
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
 
3887
                           _("the interface uses a hostdev mode, "
 
3888
                             "but has no hostdev"));
 
3889
            goto error;
 
3890
        }
 
3891
 
 
3892
        /* find the matching interface and increment its connections */
 
3893
        for (ii = 0; ii < netdef->nForwardIfs; ii++) {
 
3894
            if (netdef->forwardIfs[ii].type
 
3895
                == VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_PCI &&
 
3896
                virDevicePCIAddressEqual(&hostdev->source.subsys.u.pci,
 
3897
                                         &netdef->forwardIfs[ii].device.pci)) {
 
3898
                dev = &netdef->forwardIfs[ii];
 
3899
                break;
 
3900
            }
 
3901
        }
 
3902
        /* dev points at the physical device we want to use */
 
3903
        if (!dev) {
 
3904
            virReportError(VIR_ERR_INTERNAL_ERROR,
 
3905
                           _("network '%s' doesn't have "
 
3906
                             "PCI device %04x:%02x:%02x.%x in use by domain"),
 
3907
                           netdef->name,
 
3908
                           hostdev->source.subsys.u.pci.domain,
 
3909
                           hostdev->source.subsys.u.pci.bus,
 
3910
                           hostdev->source.subsys.u.pci.slot,
 
3911
                           hostdev->source.subsys.u.pci.function);
 
3912
                goto error;
 
3913
        }
 
3914
 
 
3915
        /* PASSTHROUGH mode, PRIVATE Mode + 802.1Qbh, and hostdev (PCI
 
3916
         * passthrough) all require exclusive access to a device, so
 
3917
         * current connections count must be 0 in those cases.
 
3918
         */
 
3919
        if ((dev->connections > 0) &&
 
3920
            netdef->forwardType == VIR_NETWORK_FORWARD_HOSTDEV) {
 
3921
            virReportError(VIR_ERR_INTERNAL_ERROR,
 
3922
                           _("network '%s' claims the PCI device at "
 
3923
                             "domain=%d bus=%d slot=%d function=%d "
 
3924
                             "is already in use by a different domain"),
 
3925
                           netdef->name,
 
3926
                           dev->device.pci.domain, dev->device.pci.bus,
 
3927
                           dev->device.pci.slot, dev->device.pci.function);
 
3928
            goto error;
 
3929
        }
 
3930
 
 
3931
        /* we are now assured of success, so mark the allocation */
 
3932
        dev->connections++;
 
3933
        VIR_DEBUG("Using physical device %04x:%02x:%02x.%x, connections %d",
 
3934
                  dev->device.pci.domain, dev->device.pci.bus,
 
3935
                  dev->device.pci.slot, dev->device.pci.function,
 
3936
                  dev->connections);
3086
3937
    }
3087
3938
 
 
3939
success:
 
3940
    netdef->connections++;
 
3941
    VIR_DEBUG("Using network %s, %d connections",
 
3942
              netdef->name, netdef->connections);
3088
3943
    ret = 0;
3089
3944
cleanup:
3090
3945
    if (network)
3091
3946
        virNetworkObjUnlock(network);
3092
3947
    return ret;
 
3948
 
 
3949
error:
 
3950
    goto cleanup;
3093
3951
}
3094
3952
 
3095
3953
 
3107
3965
networkReleaseActualDevice(virDomainNetDefPtr iface)
3108
3966
{
3109
3967
    struct network_driver *driver = driverState;
3110
 
    virNetworkObjPtr network = NULL;
 
3968
    enum virDomainNetType actualType = virDomainNetGetActualType(iface);
 
3969
    virNetworkObjPtr network;
3111
3970
    virNetworkDefPtr netdef;
3112
 
    const char *actualDev;
3113
 
    int ret = -1;
 
3971
    virNetworkForwardIfDefPtr dev = NULL;
 
3972
    int ii, ret = -1;
3114
3973
 
3115
3974
    if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK)
3116
3975
       return 0;
3117
3976
 
3118
 
    if (!iface->data.network.actual ||
3119
 
        (virDomainNetGetActualType(iface) != VIR_DOMAIN_NET_TYPE_DIRECT)) {
 
3977
    networkDriverLock(driver);
 
3978
    network = virNetworkFindByName(&driver->networks, iface->data.network.name);
 
3979
    networkDriverUnlock(driver);
 
3980
    if (!network) {
 
3981
        virReportError(VIR_ERR_NO_NETWORK,
 
3982
                       _("no network with matching name '%s'"),
 
3983
                       iface->data.network.name);
 
3984
        goto error;
 
3985
    }
 
3986
    netdef = network->def;
 
3987
 
 
3988
    if ((!iface->data.network.actual) ||
 
3989
        ((actualType != VIR_DOMAIN_NET_TYPE_DIRECT) &&
 
3990
         (actualType != VIR_DOMAIN_NET_TYPE_HOSTDEV))) {
3120
3991
        VIR_DEBUG("Nothing to release to network %s", iface->data.network.name);
3121
 
        ret = 0;
3122
 
        goto cleanup;
3123
 
    }
3124
 
 
3125
 
    networkDriverLock(driver);
3126
 
    network = virNetworkFindByName(&driver->networks, iface->data.network.name);
3127
 
    networkDriverUnlock(driver);
3128
 
    if (!network) {
3129
 
        networkReportError(VIR_ERR_NO_NETWORK,
3130
 
                           _("no network with matching name '%s'"),
3131
 
                           iface->data.network.name);
3132
 
        goto cleanup;
3133
 
    }
3134
 
 
3135
 
    actualDev = virDomainNetGetActualDirectDev(iface);
3136
 
    if (!actualDev) {
3137
 
        networkReportError(VIR_ERR_INTERNAL_ERROR,
3138
 
                           "%s", _("the interface uses a direct mode, but has no source dev"));
3139
 
        goto cleanup;
3140
 
    }
3141
 
 
3142
 
    netdef = network->def;
 
3992
        goto success;
 
3993
    }
 
3994
 
3143
3995
    if (netdef->nForwardIfs == 0) {
3144
 
        networkReportError(VIR_ERR_INTERNAL_ERROR,
3145
 
                           _("network '%s' uses a direct mode, but has no forward dev and no interface pool"),
3146
 
                           netdef->name);
3147
 
        goto cleanup;
3148
 
    } else {
3149
 
        int ii;
3150
 
        virNetworkForwardIfDefPtr dev = NULL;
3151
 
 
3152
 
        for (ii = 0; ii < netdef->nForwardIfs; ii++) {
3153
 
            if (STREQ(actualDev, netdef->forwardIfs[ii].dev)) {
3154
 
                dev = &netdef->forwardIfs[ii];
3155
 
                break;
3156
 
            }
3157
 
        }
3158
 
        /* dev points at the physical device we've been using */
3159
 
        if (!dev) {
3160
 
            networkReportError(VIR_ERR_INTERNAL_ERROR,
3161
 
                               _("network '%s' doesn't have dev='%s' in use by domain"),
3162
 
                               netdef->name, actualDev);
3163
 
            goto cleanup;
3164
 
        }
3165
 
 
3166
 
        dev->usageCount--;
3167
 
        VIR_DEBUG("Releasing physical device %s, usageCount %d",
3168
 
                  dev->dev, dev->usageCount);
 
3996
        virReportError(VIR_ERR_INTERNAL_ERROR,
 
3997
                       _("network '%s' uses a direct/hostdev mode, but "
 
3998
                         "has no forward dev and no interface pool"),
 
3999
                       netdef->name);
 
4000
        goto error;
3169
4001
    }
3170
4002
 
 
4003
    if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
 
4004
        const char *actualDev;
 
4005
 
 
4006
        actualDev = virDomainNetGetActualDirectDev(iface);
 
4007
        if (!actualDev) {
 
4008
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
 
4009
                           _("the interface uses a direct mode, "
 
4010
                             "but has no source dev"));
 
4011
            goto error;
 
4012
        }
 
4013
 
 
4014
        for (ii = 0; ii < netdef->nForwardIfs; ii++) {
 
4015
            if (netdef->forwardIfs[ii].type
 
4016
                == VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_NETDEV &&
 
4017
                STREQ(actualDev, netdef->forwardIfs[ii].device.dev)) {
 
4018
                dev = &netdef->forwardIfs[ii];
 
4019
                break;
 
4020
            }
 
4021
        }
 
4022
 
 
4023
        if (!dev) {
 
4024
            virReportError(VIR_ERR_INTERNAL_ERROR,
 
4025
                           _("network '%s' doesn't have dev='%s' "
 
4026
                             "in use by domain"),
 
4027
                           netdef->name, actualDev);
 
4028
            goto error;
 
4029
        }
 
4030
 
 
4031
        dev->connections--;
 
4032
        VIR_DEBUG("Releasing physical device %s, connections %d",
 
4033
                  dev->device.dev, dev->connections);
 
4034
 
 
4035
    } else /* if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) */ {
 
4036
        virDomainHostdevDefPtr hostdev;
 
4037
 
 
4038
        hostdev = virDomainNetGetActualHostdev(iface);
 
4039
        if (!hostdev) {
 
4040
            virReportError(VIR_ERR_INTERNAL_ERROR,
 
4041
                           "%s", _("the interface uses a hostdev mode, but has no hostdev"));
 
4042
            goto error;
 
4043
        }
 
4044
 
 
4045
        for (ii = 0; ii < netdef->nForwardIfs; ii++) {
 
4046
            if (netdef->forwardIfs[ii].type
 
4047
                == VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_PCI &&
 
4048
                virDevicePCIAddressEqual(&hostdev->source.subsys.u.pci,
 
4049
                                          &netdef->forwardIfs[ii].device.pci)) {
 
4050
                dev = &netdef->forwardIfs[ii];
 
4051
                break;
 
4052
            }
 
4053
        }
 
4054
 
 
4055
        if (!dev) {
 
4056
            virReportError(VIR_ERR_INTERNAL_ERROR,
 
4057
                           _("network '%s' doesn't have "
 
4058
                             "PCI device %04x:%02x:%02x.%x in use by domain"),
 
4059
                           netdef->name,
 
4060
                           hostdev->source.subsys.u.pci.domain,
 
4061
                           hostdev->source.subsys.u.pci.bus,
 
4062
                           hostdev->source.subsys.u.pci.slot,
 
4063
                           hostdev->source.subsys.u.pci.function);
 
4064
                goto error;
 
4065
        }
 
4066
 
 
4067
        dev->connections--;
 
4068
        VIR_DEBUG("Releasing physical device %04x:%02x:%02x.%x, connections %d",
 
4069
                  dev->device.pci.domain, dev->device.pci.bus,
 
4070
                  dev->device.pci.slot, dev->device.pci.function,
 
4071
                  dev->connections);
 
4072
   }
 
4073
 
 
4074
success:
 
4075
    netdef->connections--;
 
4076
    VIR_DEBUG("Releasing network %s, %d connections",
 
4077
              netdef->name, netdef->connections);
3171
4078
    ret = 0;
3172
4079
cleanup:
3173
4080
    if (network)
3174
4081
        virNetworkObjUnlock(network);
3175
 
    virDomainActualNetDefFree(iface->data.network.actual);
3176
 
    iface->data.network.actual = NULL;
 
4082
    if (iface->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
 
4083
        virDomainActualNetDefFree(iface->data.network.actual);
 
4084
        iface->data.network.actual = NULL;
 
4085
    }
3177
4086
    return ret;
 
4087
 
 
4088
error:
 
4089
    goto cleanup;
3178
4090
}
3179
4091
 
3180
4092
/*
3201
4113
{
3202
4114
    int ret = -1;
3203
4115
    struct network_driver *driver = driverState;
3204
 
    virNetworkObjPtr network = NULL;
 
4116
    virNetworkObjPtr network;
3205
4117
    virNetworkDefPtr netdef;
3206
4118
    virNetworkIpDefPtr ipdef;
3207
4119
    virSocketAddr addr;
3213
4125
    network = virNetworkFindByName(&driver->networks, netname);
3214
4126
    networkDriverUnlock(driver);
3215
4127
    if (!network) {
3216
 
        networkReportError(VIR_ERR_NO_NETWORK,
3217
 
                           _("no network with matching name '%s'"),
3218
 
                           netname);
3219
 
        goto cleanup;
 
4128
        virReportError(VIR_ERR_NO_NETWORK,
 
4129
                       _("no network with matching name '%s'"),
 
4130
                       netname);
 
4131
        goto error;
3220
4132
    }
3221
4133
    netdef = network->def;
3222
4134
 
3227
4139
        /* if there's an ipv4def, get it's address */
3228
4140
        ipdef = virNetworkDefGetIpByIndex(netdef, AF_INET, 0);
3229
4141
        if (!ipdef) {
3230
 
            networkReportError(VIR_ERR_INTERNAL_ERROR,
3231
 
                               _("network '%s' doesn't have an IPv4 address"),
3232
 
                               netdef->name);
 
4142
            virReportError(VIR_ERR_INTERNAL_ERROR,
 
4143
                           _("network '%s' doesn't have an IPv4 address"),
 
4144
                           netdef->name);
3233
4145
            break;
3234
4146
        }
3235
4147
        addrptr = &ipdef->address;
3246
4158
    case VIR_NETWORK_FORWARD_VEPA:
3247
4159
    case VIR_NETWORK_FORWARD_PASSTHROUGH:
3248
4160
        if ((netdef->nForwardIfs > 0) && netdef->forwardIfs)
3249
 
            dev_name = netdef->forwardIfs[0].dev;
 
4161
            dev_name = netdef->forwardIfs[0].device.dev;
3250
4162
 
3251
4163
        if (!dev_name) {
3252
 
            networkReportError(VIR_ERR_INTERNAL_ERROR,
3253
 
                               _("network '%s' has no associated interface or bridge"),
3254
 
                               netdef->name);
 
4164
            virReportError(VIR_ERR_INTERNAL_ERROR,
 
4165
                           _("network '%s' has no associated interface or bridge"),
 
4166
                           netdef->name);
3255
4167
        }
3256
4168
        break;
3257
4169
    }
3258
4170
 
3259
4171
    if (dev_name) {
3260
4172
        if (virNetDevGetIPv4Address(dev_name, &addr) < 0)
3261
 
            goto cleanup;
3262
 
 
 
4173
            goto error;
3263
4174
        addrptr = &addr;
3264
4175
    }
3265
4176
 
3266
 
    if (addrptr &&
3267
 
        (*netaddr = virSocketAddrFormat(addrptr))) {
3268
 
        ret = 0;
 
4177
    if (!(addrptr &&
 
4178
          (*netaddr = virSocketAddrFormat(addrptr)))) {
 
4179
        goto error;
3269
4180
    }
3270
4181
 
 
4182
    ret = 0;
3271
4183
cleanup:
3272
4184
    if (network)
3273
4185
        virNetworkObjUnlock(network);
3274
4186
    return ret;
 
4187
 
 
4188
error:
 
4189
    goto cleanup;
3275
4190
}