static void qemuMigrationCookieNetworkXMLFormat(virBufferPtr buf, qemuMigrationCookieNetworkPtr optr) { size_t i; bool empty = true; for (i = 0; i < optr->nnets; i++) { /* If optr->net[i].vporttype is not set, there is nothing to transfer */ if (optr->net[i].vporttype != VIR_NETDEV_VPORT_PROFILE_NONE) { if (empty) { virBufferAddLit(buf, "<network>\n"); virBufferAdjustIndent(buf, 2); empty = false; } virBufferAsprintf(buf, "<interface index='%zu' vporttype='%s'", i, virNetDevVPortTypeToString(optr->net[i].vporttype)); if (optr->net[i].portdata) { virBufferAddLit(buf, ">\n"); virBufferAdjustIndent(buf, 2); virBufferEscapeString(buf, "<portdata>%s</portdata>\n", optr->net[i].portdata); virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "</interface>\n"); } else { virBufferAddLit(buf, "/>\n"); } } } if (!empty) { virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "</network>\n"); } }
int virNetDevVPortProfileFormat(virNetDevVPortProfilePtr virtPort, virBufferPtr buf) { char uuidstr[VIR_UUID_STRING_BUFLEN]; if (!virtPort || virtPort->virtPortType == VIR_NETDEV_VPORT_PROFILE_NONE) return 0; virBufferAsprintf(buf, "<virtualport type='%s'>\n", virNetDevVPortTypeToString(virtPort->virtPortType)); switch (virtPort->virtPortType) { case VIR_NETDEV_VPORT_PROFILE_8021QBG: virUUIDFormat(virtPort->u.virtPort8021Qbg.instanceID, uuidstr); virBufferAsprintf(buf, " <parameters managerid='%d' typeid='%d' " "typeidversion='%d' instanceid='%s'/>\n", virtPort->u.virtPort8021Qbg.managerID, virtPort->u.virtPort8021Qbg.typeID, virtPort->u.virtPort8021Qbg.typeIDVersion, uuidstr); break; case VIR_NETDEV_VPORT_PROFILE_8021QBH: virBufferAsprintf(buf, " <parameters profileid='%s'/>\n", virtPort->u.virtPort8021Qbh.profileID); break; case VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH: virUUIDFormat(virtPort->u.openvswitch.interfaceID, uuidstr); if (virtPort->u.openvswitch.profileID[0] == '\0') { virBufferAsprintf(buf, " <parameters interfaceid='%s'/>\n", uuidstr); } else { virBufferAsprintf(buf, " <parameters interfaceid='%s' " "profileid='%s'/>\n", uuidstr, virtPort->u.openvswitch.profileID); } break; default: virReportError(VIR_ERR_XML_ERROR, _("unexpected virtualport type %d"), virtPort->virtPortType); return -1; } virBufferAddLit(buf, "</virtualport>\n"); return 0; }
/* virNetDevVPortProfileCheckNoExtras() checks that there are no * attributes specified in this virtport that are inappropriate for * the type. if virtport == NULL or virtPortType == NONE, then the * result is always 0 (success). If an extra attribute is present, * an error is logged and -1 is returned. */ int virNetDevVPortProfileCheckNoExtras(virNetDevVPortProfilePtr virtport) { const char *extra = NULL; if (!virtport || virtport->virtPortType == VIR_NETDEV_VPORT_PROFILE_NONE) return 0; switch (virtport->virtPortType) { case VIR_NETDEV_VPORT_PROFILE_8021QBG: if (virtport->profileID[0]) extra = "profileid"; else if (virtport->interfaceID_specified) extra = "interfaceid"; break; case VIR_NETDEV_VPORT_PROFILE_8021QBH: if (virtport->managerID_specified) extra = "managerid"; else if (virtport->typeID_specified) extra = "typeid"; else if (virtport->typeIDVersion_specified) extra = "typeidversion"; else if (virtport->instanceID_specified) extra = "instanceid"; else if (virtport->interfaceID_specified) extra = "interfaceid"; break; case VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH: if (virtport->managerID_specified) extra = "managerid"; else if (virtport->typeID_specified) extra = "typeid"; else if (virtport->typeIDVersion_specified) extra = "typeidversion"; else if (virtport->instanceID_specified) extra = "instanceid"; break; } if (extra) { virReportError(VIR_ERR_XML_ERROR, _("extra %s unsupported in <virtualport type='%s'>"), extra, virNetDevVPortTypeToString(virtport->virtPortType)); return -1; } return 0; }
static int qemuDomainHostdevNetConfigVirtPortProfile(const char *linkdev, int vf, virNetDevVPortProfilePtr virtPort, const virMacAddrPtr macaddr, const unsigned char *uuid, int associate) { int ret = -1; if (!virtPort) return ret; switch(virtPort->virtPortType) { case VIR_NETDEV_VPORT_PROFILE_NONE: case VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH: case VIR_NETDEV_VPORT_PROFILE_8021QBG: case VIR_NETDEV_VPORT_PROFILE_LAST: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("virtualport type %s is " "currently not supported on interfaces of type " "hostdev"), virNetDevVPortTypeToString(virtPort->virtPortType)); break; case VIR_NETDEV_VPORT_PROFILE_8021QBH: if (associate) ret = virNetDevVPortProfileAssociate(NULL, virtPort, macaddr, linkdev, vf, uuid, VIR_NETDEV_VPORT_PROFILE_OP_CREATE, false); else ret = virNetDevVPortProfileDisassociate(NULL, virtPort, macaddr, linkdev, vf, VIR_NETDEV_VPORT_PROFILE_OP_DESTROY); break; } return ret; }
int qemuDomainHostdevNetConfigReplace(virDomainHostdevDefPtr hostdev, const unsigned char *uuid, char *stateDir) { char *linkdev = NULL; virNetDevVlanPtr vlan; virNetDevVPortProfilePtr virtPort; int ret = -1; int vf = -1; int vlanid = -1; int port_profile_associate = 1; int isvf; isvf = qemuDomainHostdevIsVirtualFunction(hostdev); if (isvf <= 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Interface type hostdev is currently supported on" " SR-IOV Virtual Functions only")); return ret; } if (qemuDomainHostdevNetDevice(hostdev, &linkdev, &vf) < 0) return ret; vlan = virDomainNetGetActualVlan(hostdev->parent.data.net); virtPort = virDomainNetGetActualVirtPortProfile( hostdev->parent.data.net); if (virtPort) { if (vlan) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("direct setting of the vlan tag is not allowed " "for hostdev devices using %s mode"), virNetDevVPortTypeToString(virtPort->virtPortType)); goto cleanup; } ret = qemuDomainHostdevNetConfigVirtPortProfile(linkdev, vf, virtPort, &hostdev->parent.data.net->mac, uuid, port_profile_associate); } else { /* Set only mac and vlan */ if (vlan) { if (vlan->nTags != 1 || vlan->trunk) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("vlan trunking is not supported " "by SR-IOV network devices")); goto cleanup; } if (vf == -1) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("vlan can only be set for SR-IOV VFs, but " "%s is not a VF"), linkdev); goto cleanup; } vlanid = vlan->tag[0]; } else if (vf >= 0) { vlanid = 0; /* assure any current vlan tag is reset */ } ret = virNetDevReplaceNetConfig(linkdev, vf, &hostdev->parent.data.net->mac, vlanid, stateDir); } cleanup: VIR_FREE(linkdev); return ret; }
/* virNetDevVPortProfileMerge() - merge the attributes in mods into * orig. If anything that is set in mods has already been set in orig * *and doesn't match*, log an error and return -1, otherwise return 0. */ static int virNetDevVPortProfileMerge(virNetDevVPortProfilePtr orig, virNetDevVPortProfilePtr mods) { enum virNetDevVPortProfile otype; if (!orig || !mods) return 0; otype = orig->virtPortType; if (mods->virtPortType != VIR_NETDEV_VPORT_PROFILE_NONE) { if (otype != VIR_NETDEV_VPORT_PROFILE_NONE && otype != mods->virtPortType) { virReportError(VIR_ERR_XML_ERROR, _("attempt to merge virtualports " "with mismatched types (%s and %s)"), virNetDevVPortTypeToString(otype), virNetDevVPortTypeToString(mods->virtPortType)); return -1; } otype = orig->virtPortType = mods->virtPortType; } if (mods->managerID_specified && (otype == VIR_NETDEV_VPORT_PROFILE_8021QBG || otype == VIR_NETDEV_VPORT_PROFILE_NONE)) { if (orig->managerID_specified && (orig->managerID != mods->managerID)) { virReportError(VIR_ERR_XML_ERROR, _("attempt to merge virtualports " "with mismatched managerids (%d and %d)"), orig->managerID, mods->managerID); return -1; } orig->managerID = mods->managerID; orig->managerID_specified = true; } if (mods->typeID_specified && (otype == VIR_NETDEV_VPORT_PROFILE_8021QBG || otype == VIR_NETDEV_VPORT_PROFILE_NONE)) { if (orig->typeID_specified && (orig->typeID != mods->typeID)) { virReportError(VIR_ERR_XML_ERROR, _("attempt to merge virtualports " "with mismatched typeids (%d and %d)"), orig->typeID, mods->typeID); return -1; } orig->typeID = mods->typeID; orig->typeID_specified = true; } if (mods->typeIDVersion_specified && (otype == VIR_NETDEV_VPORT_PROFILE_8021QBG || otype == VIR_NETDEV_VPORT_PROFILE_NONE)) { if (orig->typeIDVersion_specified && (orig->typeIDVersion != mods->typeIDVersion)) { virReportError(VIR_ERR_XML_ERROR, _("attempt to merge virtualports with " "mismatched typeidversions (%d and %d)"), orig->typeIDVersion, mods->typeIDVersion); return -1; } orig->typeIDVersion = mods->typeIDVersion; orig->typeIDVersion_specified = true; } if (mods->instanceID_specified && (otype == VIR_NETDEV_VPORT_PROFILE_8021QBG || otype == VIR_NETDEV_VPORT_PROFILE_NONE)) { if (orig->instanceID_specified && memcmp(orig->instanceID, mods->instanceID, sizeof(orig->instanceID))) { char origuuid[VIR_UUID_STRING_BUFLEN]; char modsuuid[VIR_UUID_STRING_BUFLEN]; virReportError(VIR_ERR_XML_ERROR, _("attempt to merge virtualports with " "mismatched instanceids ('%s' and '%s')"), virUUIDFormat(orig->instanceID, origuuid), virUUIDFormat(mods->instanceID, modsuuid)); return -1; } memcpy(orig->instanceID, mods->instanceID, sizeof(orig->instanceID)); orig->instanceID_specified = true; } if (mods->interfaceID_specified && (otype == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH || otype == VIR_NETDEV_VPORT_PROFILE_NONE)) { if (orig->interfaceID_specified && memcmp(orig->interfaceID, mods->interfaceID, sizeof(orig->interfaceID))) { char origuuid[VIR_UUID_STRING_BUFLEN]; char modsuuid[VIR_UUID_STRING_BUFLEN]; virReportError(VIR_ERR_XML_ERROR, _("attempt to merge virtualports with " "mismatched interfaceids ('%s' and '%s')"), virUUIDFormat(orig->interfaceID, origuuid), virUUIDFormat(mods->interfaceID, modsuuid)); return -1; } memcpy(orig->interfaceID, mods->interfaceID, sizeof(orig->interfaceID)); orig->interfaceID_specified = true; } if (mods->profileID[0] && (otype == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH || otype == VIR_NETDEV_VPORT_PROFILE_8021QBH || otype == VIR_NETDEV_VPORT_PROFILE_NONE)) { if (orig->profileID[0] && STRNEQ(orig->profileID, mods->profileID)) { virReportError(VIR_ERR_XML_ERROR, _("attempt to merge virtualports with " "mismatched profileids ('%s' and '%s')"), orig->profileID, mods->profileID); return -1; } if (virStrcpyStatic(orig->profileID, mods->profileID) == NULL) { /* this should never happen - it indicates mods->profileID * isn't properly null terminated. */ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("corrupted profileid string")); return -1; } } return 0; }
/* virNetDevVPortProfileCheckComplete() checks that all attributes * required for the type of virtport are specified. When * generateMissing is true, any missing attribute that can be * autogenerated, will be (instanceid, interfaceid). If virtport == * NULL or virtPortType == NONE, then the result is always 0 * (success). If a required attribute is missing, an error is logged * and -1 is returned. */ int virNetDevVPortProfileCheckComplete(virNetDevVPortProfilePtr virtport, bool generateMissing) { const char *missing = NULL; if (!virtport || virtport->virtPortType == VIR_NETDEV_VPORT_PROFILE_NONE) return 0; switch (virtport->virtPortType) { case VIR_NETDEV_VPORT_PROFILE_8021QBG: if (!virtport->managerID_specified) { missing = "managerid"; } else if (!virtport->typeID_specified) { missing = "typeid"; } else if (!virtport->typeIDVersion_specified) { missing = "typeidversion"; } else if (!virtport->instanceID_specified) { if (generateMissing) { if (virUUIDGenerate(virtport->instanceID) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("cannot generate a random uuid for instanceid")); return -1; } virtport->instanceID_specified = true; } else { missing = "instanceid"; } } break; case VIR_NETDEV_VPORT_PROFILE_8021QBH: if (!virtport->profileID[0]) missing = "profileid"; break; case VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH: /* profileid is optional for openvswitch */ if (!virtport->interfaceID_specified) { if (generateMissing) { if (virUUIDGenerate(virtport->interfaceID) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("cannot generate a random uuid for interfaceid")); return -1; } virtport->interfaceID_specified = true; } else { missing = "interfaceid"; } } break; } if (missing) { virReportError(VIR_ERR_XML_ERROR, _("missing %s in <virtualport type='%s'>"), missing, virNetDevVPortTypeToString(virtport->virtPortType)); return -1; } return 0; }
int virNetDevVPortProfileFormat(virNetDevVPortProfilePtr virtPort, virBufferPtr buf) { enum virNetDevVPortProfile type; bool noParameters; if (!virtPort) return 0; noParameters = !(virtPort->managerID_specified || virtPort->typeID_specified || virtPort->typeIDVersion_specified || virtPort->instanceID_specified || virtPort->profileID[0] || virtPort->interfaceID_specified); type = virtPort->virtPortType; if (type == VIR_NETDEV_VPORT_PROFILE_NONE) { if (noParameters) return 0; virBufferAddLit(buf, "<virtualport>\n"); } else { if (noParameters) { virBufferAsprintf(buf, "<virtualport type='%s'/>\n", virNetDevVPortTypeToString(type)); return 0; } else { virBufferAsprintf(buf, "<virtualport type='%s'>\n", virNetDevVPortTypeToString(type)); } } virBufferAddLit(buf, " <parameters"); if (virtPort->managerID_specified && (type == VIR_NETDEV_VPORT_PROFILE_8021QBG || type == VIR_NETDEV_VPORT_PROFILE_NONE)) { virBufferAsprintf(buf, " managerid='%d'", virtPort->managerID); } if (virtPort->typeID_specified && (type == VIR_NETDEV_VPORT_PROFILE_8021QBG || type == VIR_NETDEV_VPORT_PROFILE_NONE)) { virBufferAsprintf(buf, " typeid='%d'", virtPort->typeID); } if (virtPort->typeIDVersion_specified && (type == VIR_NETDEV_VPORT_PROFILE_8021QBG || type == VIR_NETDEV_VPORT_PROFILE_NONE)) { virBufferAsprintf(buf, " typeidversion='%d'", virtPort->typeIDVersion); } if (virtPort->instanceID_specified && (type == VIR_NETDEV_VPORT_PROFILE_8021QBG || type == VIR_NETDEV_VPORT_PROFILE_NONE)) { char uuidstr[VIR_UUID_STRING_BUFLEN]; virUUIDFormat(virtPort->instanceID, uuidstr); virBufferAsprintf(buf, " instanceid='%s'", uuidstr); } if (virtPort->interfaceID_specified && (type == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH || type == VIR_NETDEV_VPORT_PROFILE_NONE)) { char uuidstr[VIR_UUID_STRING_BUFLEN]; virUUIDFormat(virtPort->interfaceID, uuidstr); virBufferAsprintf(buf, " interfaceid='%s'", uuidstr); } if (virtPort->profileID[0] && (type == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH || type == VIR_NETDEV_VPORT_PROFILE_8021QBH || type == VIR_NETDEV_VPORT_PROFILE_NONE)) { virBufferAsprintf(buf, " profileid='%s'", virtPort->profileID); } virBufferAddLit(buf, "/>\n"); virBufferAddLit(buf, "</virtualport>\n"); return 0; }