475
/* networkKillDaemon:
477
* kill the specified pid/name, and wait a bit to make sure it's dead.
480
networkKillDaemon(pid_t pid, const char *daemonName, const char *networkName)
483
const char *signame = "TERM";
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
490
for (ii = 0; ii < 25; ii++) {
498
if (kill(pid, signum) < 0) {
499
if (errno == ESRCH) {
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)));
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.
527
VIR_WARN("Timed out waiting after SIG%s to %s process %d "
529
signame, daemonName, pid, networkName);
424
535
networkBuildDnsmasqHostsfile(dnsmasqContext *dctx,
425
536
virNetworkIpDefPtr ipdef,
797
networkStartRadvd(virNetworkObjPtr network)
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;
806
virNetworkIpDefPtr ipdef;
808
network->radvdPid = -1;
810
if (!virFileIsExecutable(RADVD)) {
811
virReportSystemError(errno,
812
_("Cannot find %s - "
813
"Possibly the package isn't installed"),
818
if (virFileMakePath(NETWORK_PID_DIR) < 0) {
819
virReportSystemError(errno,
820
_("cannot create directory %s"),
824
if (virFileMakePath(RADVD_STATE_DIR) < 0) {
825
virReportSystemError(errno,
826
_("cannot create directory %s"),
831
/* construct pidfile name */
832
if (!(radvdpidbase = networkRadvdPidfileBasename(network->def->name))) {
836
if (!(pidfile = virPidFileBuildPath(NETWORK_PID_DIR, radvdpidbase))) {
841
/* create radvd config file appropriate for this network */
924
/* networkRefreshDhcpDaemon:
925
* Update dnsmasq config files, then send a SIGHUP so that it rereads
928
* Returns 0 on success, -1 on failure.
931
networkRefreshDhcpDaemon(virNetworkObjPtr network)
934
virNetworkIpDefPtr ipdef;
935
dnsmasqContext *dctx = NULL;
937
/* if there's no running dnsmasq, just start it */
938
if (network->dnsmasqPid <= 0 || (kill(network->dnsmasqPid, 0) < 0))
939
return networkStartDhcpDaemon(network);
941
/* Look for first IPv4 address that has dhcp defined. */
942
/* We support dhcp config on 1 IPv4 interface only. */
944
(ipdef = virNetworkDefGetIpByIndex(network->def, AF_INET, ii));
946
if (ipdef->nranges || ipdef->nhosts)
949
/* If no IPv4 addresses had dhcp info, pick the first (if there were any). */
951
ipdef = virNetworkDefGetIpByIndex(network->def, AF_INET, 0);
954
/* no <ip> elements, so nothing to do */
958
if (!(dctx = dnsmasqContextNew(network->def->name, DNSMASQ_STATE_DIR)))
961
if (networkBuildDnsmasqHostsfile(dctx, ipdef, network->def->dns) < 0)
964
if ((ret = dnsmasqSave(dctx)) < 0)
967
ret = kill(network->dnsmasqPid, SIGHUP);
969
dnsmasqContextFree(dctx);
973
/* networkRestartDhcpDaemon:
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).
978
* Returns 0 on success, -1 on failure.
981
networkRestartDhcpDaemon(virNetworkObjPtr network)
983
/* if there is a running dnsmasq, kill it */
984
if (network->dnsmasqPid > 0) {
985
networkKillDaemon(network->dnsmasqPid, "dnsmasq",
987
network->dnsmasqPid = -1;
989
/* now start dnsmasq if it should be started */
990
return networkStartDhcpDaemon(network);
994
networkRadvdConfContents(virNetworkObjPtr network, char **configstr)
996
virBuffer configbuf = VIR_BUFFER_INITIALIZER;
998
virNetworkIpDefPtr ipdef;
999
bool v6present = false;
1003
/* create radvd config file appropriate for this network;
1004
* IgnoreIfMissing allows radvd to start even when the bridge is down
842
1006
virBufferAsprintf(&configbuf, "interface %s\n"
844
1008
" AdvSendAdvert on;\n"
845
1009
" AdvManagedFlag off;\n"
846
1010
" AdvOtherConfigFlag off;\n"
1011
" IgnoreIfMissing on;\n"
848
1013
network->def->bridge);
1015
/* add a section for each IPv6 address in the config */
850
1017
(ipdef = virNetworkDefGetIpByIndex(network->def, AF_INET6, ii));
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);
862
1030
if (!(netaddr = virSocketAddrFormat(&ipdef->address)))
872
1040
VIR_FREE(netaddr);
875
virBufferAddLit(&configbuf, "};\n");
877
if (virBufferError(&configbuf)) {
1043
/* only create the string if we found at least one IPv6 address */
1045
virBufferAddLit(&configbuf, "};\n");
1047
if (virBufferError(&configbuf)) {
1048
virReportOOMError();
1051
if (!(*configstr = virBufferContentAndReset(&configbuf))) {
1052
virReportOOMError();
1059
virBufferFreeAndReset(&configbuf);
1063
/* write file and return it's name (which must be freed by caller) */
1065
networkRadvdConfWrite(virNetworkObjPtr network, char **configFile)
1068
char *configStr = NULL;
1069
char *myConfigFile = NULL;
1072
configFile = &myConfigFile;
1076
if (networkRadvdConfContents(network, &configStr) < 0)
881
if (!(configstr = virBufferContentAndReset(&configbuf))) {
886
1084
/* construct the filename */
887
if (!(configfile = networkRadvdConfigFileName(network->def->name))) {
1085
if (!(*configFile = networkRadvdConfigFileName(network->def->name))) {
888
1086
virReportOOMError();
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'"),
1099
VIR_FREE(configStr);
1100
VIR_FREE(myConfigFile);
1105
networkStartRadvd(virNetworkObjPtr network)
1107
char *pidfile = NULL;
1108
char *radvdpidbase = NULL;
1109
char *configfile = NULL;
1110
virCommandPtr cmd = NULL;
1113
network->radvdPid = -1;
1115
if (!virNetworkDefGetIpByIndex(network->def, AF_INET6, 0)) {
1116
/* no IPv6 addresses, so we don't need to run radvd */
1121
if (!virFileIsExecutable(RADVD)) {
1122
virReportSystemError(errno,
1123
_("Cannot find %s - "
1124
"Possibly the package isn't installed"),
1129
if (virFileMakePath(NETWORK_PID_DIR) < 0) {
1130
virReportSystemError(errno,
1131
_("cannot create directory %s"),
1135
if (virFileMakePath(RADVD_STATE_DIR) < 0) {
1136
virReportSystemError(errno,
1137
_("cannot create directory %s"),
1142
/* construct pidfile name */
1143
if (!(radvdpidbase = networkRadvdPidfileBasename(network->def->name))) {
1144
virReportOOMError();
1147
if (!(pidfile = virPidFileBuildPath(NETWORK_PID_DIR, radvdpidbase))) {
1148
virReportOOMError();
1152
if (networkRadvdConfWrite(network, &configfile) < 0)
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)
919
if (virPidFileRead(NETWORK_PID_DIR, radvdpidbase,
920
&network->radvdPid) < 0)
1175
if (virPidFileRead(NETWORK_PID_DIR, radvdpidbase, &network->radvdPid) < 0)
925
1180
virCommandFree(cmd);
926
1181
VIR_FREE(configfile);
928
virBufferFreeAndReset(&configbuf);
929
1182
VIR_FREE(radvdpidbase);
930
1183
VIR_FREE(pidfile);
1188
networkRefreshRadvd(virNetworkObjPtr network)
1190
/* if there's no running radvd, just start it */
1191
if (network->radvdPid <= 0 || (kill(network->radvdPid, 0) < 0))
1192
return networkStartRadvd(network);
1194
if (!virNetworkDefGetIpByIndex(network->def, AF_INET6, 0)) {
1195
/* no IPv6 addresses, so we don't need to run radvd */
1199
if (networkRadvdConfWrite(network, NULL) < 0)
1202
return kill(network->radvdPid, SIGHUP);
1206
/* currently unused, so it causes a build error unless we #if it out */
1208
networkRestartRadvd(virNetworkObjPtr network)
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).
1218
if ((networkKillDaemon(network->dnsmasqPid, "radvd",
1219
network->def->name) >= 0) &&
1220
((radvdpidbase = networkRadvdPidfileBasename(network->def->name))
1222
virPidFileDelete(NETWORK_PID_DIR, radvdpidbase);
1223
VIR_FREE(radvdpidbase);
1225
network->radvdPid = -1;
1227
/* now start radvd if it should be started */
1228
return networkStartRadvd(network);
1232
/* SIGHUP/restart any dnsmasq or radvd daemons.
1233
* This should be called when libvirtd is restarted.
1236
networkRefreshDaemons(struct network_driver *driver)
1240
VIR_INFO("Refreshing network daemons");
1242
for (i = 0 ; i < driver->networks.count ; i++) {
1243
virNetworkObjPtr network = driver->networks.objs[i];
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
1256
networkRefreshDhcpDaemon(network);
1257
networkRefreshRadvd(network);
1259
virNetworkObjUnlock(network);
935
1264
networkAddMasqueradingIptablesRules(struct network_driver *driver,
936
1265
virNetworkObjPtr network,
937
1266
virNetworkIpDefPtr ipdef)
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);
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);
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);
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);
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);
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);
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);
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);
2624
networkValidate(virNetworkDefPtr def)
2627
bool vlanUsed, vlanAllowed, badVlanUse = false;
2628
virPortGroupDefPtr defaultPortGroup = NULL;
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.
2635
vlanAllowed = (def->forwardType == VIR_NETWORK_FORWARD_BRIDGE &&
2636
def->virtPortProfile &&
2637
def->virtPortProfile->virtPortType == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH);
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.
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) {
2653
} else if (!vlanAllowed) {
2654
/* virtualport taken from base network definition */
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);
2668
defaultPortGroup = &def->portGroups[ii];
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.
2678
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
2679
_("<vlan> element specified for network %s, "
2680
"whose type doesn't support vlan configuration"),
2257
2687
static virNetworkPtr networkCreate(virConnectPtr conn, const char *xml) {
2258
2688
struct network_driver *driver = conn->networkPrivateData;
2259
2689
virNetworkDefPtr def;
2918
networkUpdate(virNetworkPtr net,
2919
unsigned int command,
2920
unsigned int section,
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;
2932
virCheckFlags(VIR_NETWORK_UPDATE_AFFECT_LIVE |
2933
VIR_NETWORK_UPDATE_AFFECT_CONFIG,
2936
networkDriverLock(driver);
2938
network = virNetworkFindByUUID(&driver->networks, net->uuid);
2940
virReportError(VIR_ERR_NO_NETWORK,
2941
"%s", _("no network with matching uuid"));
2945
/* see if we are listening for dhcp pre-modification */
2947
(ipdef = virNetworkDefGetIpByIndex(network->def, AF_INET, ii));
2949
if (ipdef->nranges || ipdef->nhosts) {
2950
oldDhcpActive = true;
2955
/* VIR_NETWORK_UPDATE_AFFECT_CURRENT means "change LIVE if network
2956
* is active, else change CONFIG
2958
isActive = virNetworkObjIsActive(network);
2959
if ((flags & (VIR_NETWORK_UPDATE_AFFECT_LIVE |
2960
VIR_NETWORK_UPDATE_AFFECT_CONFIG)) ==
2961
VIR_NETWORK_UPDATE_AFFECT_CURRENT) {
2963
flags |= VIR_NETWORK_UPDATE_AFFECT_LIVE;
2965
flags |= VIR_NETWORK_UPDATE_AFFECT_CONFIG;
2968
/* update the network config in memory/on disk */
2969
if (virNetworkObjUpdate(network, command, section, parentIndex, xml, flags) < 0)
2972
if (flags & VIR_NETWORK_UPDATE_AFFECT_CONFIG) {
2973
/* save updated persistent config to disk */
2974
if (virNetworkSaveConfig(driver->networkConfigDir,
2975
virNetworkObjGetPersistentDef(network)) < 0) {
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.
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.
2993
if (networkRestartDhcpDaemon(network) < 0)
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)
3002
bool newDhcpActive = false;
3005
(ipdef = virNetworkDefGetIpByIndex(network->def, AF_INET, ii));
3007
if (ipdef->nranges || ipdef->nhosts) {
3008
newDhcpActive = true;
3013
if ((newDhcpActive != oldDhcpActive &&
3014
networkRestartDhcpDaemon(network) < 0) ||
3015
networkRefreshDhcpDaemon(network) < 0) {
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
3026
if (networkRefreshDhcpDaemon(network) < 0)
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.
3035
if (networkRefreshRadvd(network) < 0)
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)
3052
/* save current network state to disk */
3053
if ((ret = virNetworkSaveStatus(NETWORK_STATE_DIR, network)) < 0)
3059
virNetworkObjUnlock(network);
3060
networkDriverUnlock(driver);
2478
3064
static int networkStart(virNetworkPtr net) {
2479
3065
struct network_driver *driver = net->conn->networkPrivateData;
2480
3066
virNetworkObjPtr network;
2735
3323
* "backend" function table.
3326
/* networkCreateInterfacePool:
3327
* @netdef: the original NetDef from the network
3329
* Creates an implicit interface pool of VF's when a PF dev is given
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;
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);
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);
3353
if ((VIR_ALLOC_N(netdef->forwardIfs, num_virt_fns)) < 0) {
3354
virReportOOMError();
3358
netdef->nForwardIfs = num_virt_fns;
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;
3367
netdef->forwardIfs[ii].device.dev = strdup(vfname[ii]);
3368
if (!netdef->forwardIfs[ii].device.dev) {
3369
virReportOOMError();
3374
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
3375
_("Direct mode types require interface names"));
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;
3391
for (ii = 0; ii < num_virt_fns; ii++) {
3392
VIR_FREE(vfname[ii]);
3393
VIR_FREE(virt_fns[ii]);
2738
3400
/* networkAllocateActualDevice:
2739
3401
* @iface: the original NetDef from the domain
2817
3484
if (!iface->data.network.actual
2818
3485
&& (VIR_ALLOC(iface->data.network.actual) < 0)) {
2819
3486
virReportOOMError();
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();
3497
/* merge virtualports from interface, network, and portgroup to
3498
* arrive at actual virtualport to use
3500
if (virNetDevVPortProfileMerge3(&iface->data.network.actual->virtPortProfile,
3501
iface->virtPortProfile,
3502
netdef->virtPortProfile,
3504
? portgroup->virtPortProfile : NULL) < 0) {
3507
virtport = iface->data.network.actual->virtPortProfile;
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),
3520
} else if (netdef->forwardType == VIR_NETWORK_FORWARD_HOSTDEV) {
3522
if (!iface->data.network.actual
3523
&& (VIR_ALLOC(iface->data.network.actual) < 0)) {
3524
virReportOOMError();
3528
iface->data.network.actual->type = actualType = VIR_DOMAIN_NET_TYPE_HOSTDEV;
3529
if (netdef->nForwardPfs > 0 && netdef->nForwardIfs <= 0 &&
3530
networkCreateInterfacePool(netdef) < 0) {
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];
3542
virReportError(VIR_ERR_INTERNAL_ERROR,
3543
_("network '%s' requires exclusive access "
3544
"to interfaces, but none are available"),
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;
3556
/* merge virtualports from interface, network, and portgroup to
3557
* arrive at actual virtualport to use
3559
if (virNetDevVPortProfileMerge3(&iface->data.network.actual->virtPortProfile,
3560
iface->virtPortProfile,
3561
netdef->virtPortProfile,
3563
? portgroup->virtPortProfile : NULL) < 0) {
3566
virtport = iface->data.network.actual->virtPortProfile;
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),
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;
2836
3586
/* <forward type='bridge|private|vepa|passthrough'> are all
2837
3587
* VIR_DOMAIN_NET_TYPE_DIRECT.
2863
/* Find the most specific virtportprofile and copy it */
2864
if (iface->data.network.virtPortProfile) {
2865
virtport = iface->data.network.virtPortProfile;
2868
virtport = portgroup->virtPortProfile;
2870
virtport = netdef->virtPortProfile;
3613
/* merge virtualports from interface, network, and portgroup to
3614
* arrive at actual virtualport to use
3616
if (virNetDevVPortProfileMerge3(&iface->data.network.actual->virtPortProfile,
3617
iface->virtPortProfile,
3618
netdef->virtPortProfile,
3620
? portgroup->virtPortProfile : NULL) < 0) {
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();
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),
2877
/* There are no pointers in a virtualPortProfile, so a shallow copy
2880
*iface->data.network.actual->data.direct.virtPortProfile = *virtport;
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).
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"),
3641
virReportError(VIR_ERR_INTERNAL_ERROR,
3642
_("network '%s' uses a direct mode, but "
3643
"has no forward dev and no interface pool"),
2892
virNetworkForwardIfDefPtr dev = NULL;
2894
3647
/* pick an interface from the pool */
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) {
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
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);
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);
2918
if ((VIR_ALLOC_N(netdef->forwardIfs, num_virt_fns)) < 0) {
2919
virReportOOMError();
2923
netdef->nForwardIfs = num_virt_fns;
2925
for (ii = 0; ii < netdef->nForwardIfs; ii++) {
2926
netdef->forwardIfs[ii].dev = strdup(vfname[ii]);
2927
if (!netdef->forwardIfs[ii].dev) {
2928
virReportOOMError();
2931
netdef->forwardIfs[ii].usageCount = 0;
2935
/* pick first dev with 0 usageCount */
2937
for (ii = 0; ii < netdef->nForwardIfs; ii++) {
2938
if (netdef->forwardIfs[ii].usageCount == 0) {
2939
dev = &netdef->forwardIfs[ii];
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)) {
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))) {
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];
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];
2963
3681
/* dev points at the physical device we want to use */
2965
networkReportError(VIR_ERR_INTERNAL_ERROR,
2966
_("network '%s' requires exclusive access to interfaces, but none are available"),
3683
virReportError(VIR_ERR_INTERNAL_ERROR,
3684
_("network '%s' requires exclusive access "
3685
"to interfaces, but none are available"),
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();
2975
/* we are now assured of success, so mark the allocation */
2977
VIR_DEBUG("Using physical device %s, usageCount %d",
2978
dev->dev, dev->usageCount);
3697
if (virNetDevVPortProfileCheckComplete(virtport, true) < 0)
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;
3708
if (virNetDevVlanCopy(&iface->data.network.actual->vlan, vlan) < 0)
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.
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
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))) {
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"),
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));
3744
/* we are now assured of success, so mark the allocation */
3746
if (actualType != VIR_DOMAIN_NET_TYPE_HOSTDEV) {
3747
VIR_DEBUG("Using physical device %s, %d connections",
3748
dev->device.dev, dev->connections);
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,
3758
netdef->connections++;
3759
VIR_DEBUG("Using network %s, %d connections",
3760
netdef->name, netdef->connections);
2984
for (ii = 0; ii < num_virt_fns; ii++)
2985
VIR_FREE(vfname[ii]);
2988
3766
virNetworkObjUnlock(network);
3770
if (iface->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
2990
3771
virDomainActualNetDefFree(iface->data.network.actual);
2991
3772
iface->data.network.actual = NULL;
2996
3777
/* networkNotifyActualDevice:
3007
3788
networkNotifyActualDevice(virDomainNetDefPtr iface)
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;
3794
virNetworkForwardIfDefPtr dev = NULL;
3015
3797
if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK)
3800
networkDriverLock(driver);
3801
network = virNetworkFindByName(&driver->networks, iface->data.network.name);
3802
networkDriverUnlock(driver);
3804
virReportError(VIR_ERR_NO_NETWORK,
3805
_("no network with matching name '%s'"),
3806
iface->data.network.name);
3809
netdef = network->def;
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);
3024
networkDriverLock(driver);
3025
network = virNetworkFindByName(&driver->networks, iface->data.network.name);
3026
networkDriverUnlock(driver);
3028
networkReportError(VIR_ERR_NO_NETWORK,
3029
_("no network with matching name '%s'"),
3030
iface->data.network.name);
3034
actualDev = virDomainNetGetActualDirectDev(iface);
3036
networkReportError(VIR_ERR_INTERNAL_ERROR,
3037
"%s", _("the interface uses a direct mode, but has no source dev"));
3041
netdef = network->def;
3818
if (netdef->nForwardPfs > 0 && netdef->nForwardIfs == 0 &&
3819
networkCreateInterfacePool(netdef) < 0) {
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"),
3049
virNetworkForwardIfDefPtr dev = NULL;
3051
/* find the matching interface in the pool and increment its usageCount */
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"),
3830
if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
3831
const char *actualDev;
3833
actualDev = virDomainNetGetActualDirectDev(iface);
3835
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
3836
_("the interface uses a direct mode, "
3837
"but has no source dev"));
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];
3059
3850
/* dev points at the physical device we want to use */
3061
networkReportError(VIR_ERR_INTERNAL_ERROR,
3062
_("network '%s' doesn't have dev='%s' in use by domain"),
3063
netdef->name, actualDev);
3852
virReportError(VIR_ERR_INTERNAL_ERROR,
3853
_("network '%s' doesn't have dev='%s' "
3854
"in use by domain"),
3855
netdef->name, actualDev);
3067
/* PASSTHROUGH mode, and PRIVATE Mode + 802.1Qbh both require
3068
* exclusive access to a device, so current usageCount must be
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.
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);
3082
/* we are now assured of success, so mark the allocation */
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);
3876
/* we are now assured of success, so mark the allocation */
3878
VIR_DEBUG("Using physical device %s, connections %d",
3879
dev->device.dev, dev->connections);
3881
} else /* if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) */ {
3882
virDomainHostdevDefPtr hostdev;
3884
hostdev = virDomainNetGetActualHostdev(iface);
3886
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
3887
_("the interface uses a hostdev mode, "
3888
"but has no hostdev"));
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];
3902
/* dev points at the physical device we want to use */
3904
virReportError(VIR_ERR_INTERNAL_ERROR,
3905
_("network '%s' doesn't have "
3906
"PCI device %04x:%02x:%02x.%x in use by domain"),
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);
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.
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"),
3926
dev->device.pci.domain, dev->device.pci.bus,
3927
dev->device.pci.slot, dev->device.pci.function);
3931
/* we are now assured of success, so mark the allocation */
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,
3940
netdef->connections++;
3941
VIR_DEBUG("Using network %s, %d connections",
3942
netdef->name, netdef->connections);
3091
3946
virNetworkObjUnlock(network);
3107
3965
networkReleaseActualDevice(virDomainNetDefPtr iface)
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;
3971
virNetworkForwardIfDefPtr dev = NULL;
3115
3974
if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK)
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);
3981
virReportError(VIR_ERR_NO_NETWORK,
3982
_("no network with matching name '%s'"),
3983
iface->data.network.name);
3986
netdef = network->def;
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);
3125
networkDriverLock(driver);
3126
network = virNetworkFindByName(&driver->networks, iface->data.network.name);
3127
networkDriverUnlock(driver);
3129
networkReportError(VIR_ERR_NO_NETWORK,
3130
_("no network with matching name '%s'"),
3131
iface->data.network.name);
3135
actualDev = virDomainNetGetActualDirectDev(iface);
3137
networkReportError(VIR_ERR_INTERNAL_ERROR,
3138
"%s", _("the interface uses a direct mode, but has no source dev"));
3142
netdef = network->def;
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"),
3150
virNetworkForwardIfDefPtr dev = NULL;
3152
for (ii = 0; ii < netdef->nForwardIfs; ii++) {
3153
if (STREQ(actualDev, netdef->forwardIfs[ii].dev)) {
3154
dev = &netdef->forwardIfs[ii];
3158
/* dev points at the physical device we've been using */
3160
networkReportError(VIR_ERR_INTERNAL_ERROR,
3161
_("network '%s' doesn't have dev='%s' in use by domain"),
3162
netdef->name, actualDev);
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"),
4003
if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
4004
const char *actualDev;
4006
actualDev = virDomainNetGetActualDirectDev(iface);
4008
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
4009
_("the interface uses a direct mode, "
4010
"but has no source dev"));
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];
4024
virReportError(VIR_ERR_INTERNAL_ERROR,
4025
_("network '%s' doesn't have dev='%s' "
4026
"in use by domain"),
4027
netdef->name, actualDev);
4032
VIR_DEBUG("Releasing physical device %s, connections %d",
4033
dev->device.dev, dev->connections);
4035
} else /* if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) */ {
4036
virDomainHostdevDefPtr hostdev;
4038
hostdev = virDomainNetGetActualHostdev(iface);
4040
virReportError(VIR_ERR_INTERNAL_ERROR,
4041
"%s", _("the interface uses a hostdev mode, but has no hostdev"));
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];
4056
virReportError(VIR_ERR_INTERNAL_ERROR,
4057
_("network '%s' doesn't have "
4058
"PCI device %04x:%02x:%02x.%x in use by domain"),
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);
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,
4075
netdef->connections--;
4076
VIR_DEBUG("Releasing network %s, %d connections",
4077
netdef->name, netdef->connections);
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;