conf: net: Add model enum, and netfront value

This adds a network model enum. The virDomainNetDef property
is named 'model' like most other devices.

When the XML parser or a driver calls NetSetModelString, if
the passed string is in the enum, we will set net->model,
otherwise we copy the string into net->modelstr

Add a single example for the 'netfront' xen model, and wire
that up, just to verify it's all working

Acked-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Cole Robinson <crobinso@redhat.com>
This commit is contained in:
Cole Robinson 2019-01-17 19:12:27 -05:00
parent aa3c9f34bf
commit d79a2c079c
7 changed files with 79 additions and 32 deletions

View File

@ -506,6 +506,12 @@ VIR_ENUM_IMPL(virDomainNet,
"udp",
);
VIR_ENUM_IMPL(virDomainNetModel,
VIR_DOMAIN_NET_MODEL_LAST,
"unknown",
"netfront",
);
VIR_ENUM_IMPL(virDomainNetBackend,
VIR_DOMAIN_NET_BACKEND_TYPE_LAST,
"default",
@ -2326,6 +2332,7 @@ virDomainNetDefClear(virDomainNetDefPtr def)
return;
VIR_FREE(def->modelstr);
def->model = VIR_DOMAIN_NET_MODEL_UNKNOWN;
switch (def->type) {
case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
@ -11607,20 +11614,9 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
goto error;
}
/* NIC model (see -net nic,model=?). We only check that it looks
* reasonable, not that it is a supported NIC type. FWIW kvm
* supports these types as of April 2008:
* i82551 i82557b i82559er ne2k_pci pcnet rtl8139 e1000 virtio
* QEMU PPC64 supports spapr-vlan
*/
if (model != NULL) {
if (strspn(model, NET_MODEL_CHARS) < strlen(model)) {
virReportError(VIR_ERR_INVALID_ARG, "%s",
_("Model name contains invalid characters"));
goto error;
}
VIR_STEAL_PTR(def->modelstr, model);
}
if (model != NULL &&
virDomainNetSetModelString(def, model) < 0)
goto error;
switch (def->type) {
case VIR_DOMAIN_NET_TYPE_NETWORK:
@ -21831,6 +21827,14 @@ virDomainNetDefCheckABIStability(virDomainNetDefPtr src,
return false;
}
if (src->model != dst->model) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Target network card model %s does not match source %s"),
virDomainNetModelTypeToString(dst->model),
virDomainNetModelTypeToString(src->model));
return false;
}
if (src->mtu != dst->mtu) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Target network card MTU %d does not match source %d"),
@ -29480,6 +29484,8 @@ virDomainNetGetActualTrustGuestRxFilters(virDomainNetDefPtr iface)
const char *
virDomainNetGetModelString(const virDomainNetDef *net)
{
if (net->model)
return virDomainNetModelTypeToString(net->model);
return net->modelstr;
}
@ -29487,13 +29493,31 @@ int
virDomainNetSetModelString(virDomainNetDefPtr net,
const char *model)
{
return VIR_STRDUP(net->modelstr, model);
VIR_FREE(net->modelstr);
if ((net->model = virDomainNetModelTypeFromString(model)) >= 0)
return 0;
net->model = VIR_DOMAIN_NET_MODEL_UNKNOWN;
if (!model)
return 0;
if (strspn(model, NET_MODEL_CHARS) < strlen(model)) {
virReportError(VIR_ERR_INVALID_ARG, "%s",
_("Model name contains invalid characters"));
return -1;
}
if (VIR_STRDUP(net->modelstr, model) < 0)
return -1;
return 0;
}
int
virDomainNetStreqModelString(const virDomainNetDef *net,
const char *model)
{
if (net->model)
return net->model == virDomainNetModelTypeFromString(model);
return STREQ_NULLABLE(net->modelstr, model);
}
@ -29501,6 +29525,8 @@ int
virDomainNetStrcaseeqModelString(const virDomainNetDef *net,
const char *model)
{
if (net->model)
return STRCASEEQ(virDomainNetModelTypeToString(net->model), model);
return net->modelstr && STRCASEEQ(net->modelstr, model);
}

View File

@ -839,6 +839,14 @@ typedef enum {
VIR_DOMAIN_NET_TYPE_LAST
} virDomainNetType;
/* network model types */
typedef enum {
VIR_DOMAIN_NET_MODEL_UNKNOWN,
VIR_DOMAIN_NET_MODEL_NETFRONT,
VIR_DOMAIN_NET_MODEL_LAST
} virDomainNetModelType;
/* the backend driver used for virtio interfaces */
typedef enum {
VIR_DOMAIN_NET_BACKEND_TYPE_DEFAULT, /* prefer kernel, fall back to user */
@ -898,6 +906,7 @@ struct _virDomainNetDef {
virDomainNetType type;
virMacAddr mac;
bool mac_generated; /* true if mac was *just now* auto-generated by libvirt */
int model; /* virDomainNetModelType */
char *modelstr;
union {
struct {
@ -3333,6 +3342,7 @@ VIR_ENUM_DECL(virDomainNet);
VIR_ENUM_DECL(virDomainNetBackend);
VIR_ENUM_DECL(virDomainNetVirtioTxMode);
VIR_ENUM_DECL(virDomainNetInterfaceLinkState);
VIR_ENUM_DECL(virDomainNetModel);
VIR_ENUM_DECL(virDomainChrDevice);
VIR_ENUM_DECL(virDomainChrChannelTarget);
VIR_ENUM_DECL(virDomainChrConsoleTarget);

View File

@ -478,6 +478,8 @@ virDomainNetGetActualVlan;
virDomainNetGetModelString;
virDomainNetInsert;
virDomainNetIsVirtioModel;
virDomainNetModelTypeFromString;
virDomainNetModelTypeToString;
virDomainNetNotifyActualDevice;
virDomainNetReleaseActualDevice;
virDomainNetRemove;

View File

@ -1278,7 +1278,7 @@ libxlMakeNic(virDomainDefPtr def,
if (virDomainNetGetModelString(l_nic)) {
if ((def->os.type == VIR_DOMAIN_OSTYPE_XEN ||
def->os.type == VIR_DOMAIN_OSTYPE_XENPVH) &&
!virDomainNetStreqModelString(l_nic, "netfront")) {
l_nic->model != VIR_DOMAIN_NET_MODEL_NETFRONT) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("only model 'netfront' is supported for "
"Xen PV(H) domains"));
@ -1286,7 +1286,7 @@ libxlMakeNic(virDomainDefPtr def,
}
if (VIR_STRDUP(x_nic->model, virDomainNetGetModelString(l_nic)) < 0)
goto cleanup;
if (virDomainNetStreqModelString(l_nic, "netfront"))
if (l_nic->model == VIR_DOMAIN_NET_MODEL_NETFRONT)
x_nic->nictype = LIBXL_NIC_TYPE_VIF;
else
x_nic->nictype = LIBXL_NIC_TYPE_VIF_IOEMU;

View File

@ -3799,6 +3799,14 @@ qemuDomainChangeNet(virQEMUDriverPtr driver,
goto cleanup;
}
if (olddev->model != newdev->model) {
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("cannot modify network device model from %s to %s"),
virDomainNetModelTypeToString(olddev->model),
virDomainNetModelTypeToString(newdev->model));
goto cleanup;
}
if (virDomainNetIsVirtioModel(olddev) &&
(olddev->driver.virtio.name != newdev->driver.virtio.name ||
olddev->driver.virtio.txmode != newdev->driver.virtio.txmode ||

View File

@ -1068,13 +1068,13 @@ xenParseVif(char *entry, const char *vif_typename)
VIR_STRDUP(net->script, script) < 0)
goto cleanup;
if (model[0] &&
virDomainNetSetModelString(net, model) < 0)
goto cleanup;
if (!model[0] && type[0] && STREQ(type, vif_typename) &&
virDomainNetSetModelString(net, "netfront") < 0)
goto cleanup;
if (model[0]) {
if (virDomainNetSetModelString(net, model) < 0)
goto cleanup;
} else {
if (type[0] && STREQ(type, vif_typename))
net->model = VIR_DOMAIN_NET_MODEL_NETFRONT;
}
if (vifname[0] &&
VIR_STRDUP(net->ifname, vifname) < 0)
@ -1427,7 +1427,7 @@ xenFormatNet(virConnectPtr conn,
virBufferAsprintf(&buf, ",model=%s",
virDomainNetGetModelString(net));
} else {
if (virDomainNetStreqModelString(net, "netfront"))
if (net->model == VIR_DOMAIN_NET_MODEL_NETFRONT)
virBufferAsprintf(&buf, ",type=%s", vif_typename);
else
virBufferAsprintf(&buf, ",model=%s",

View File

@ -642,12 +642,13 @@ xenParseSxprNets(virDomainDefPtr def,
}
}
if (virDomainNetSetModelString(net, model) < 0)
goto cleanup;
if (!model && type && STREQ(type, "netfront") &&
virDomainNetSetModelString(net, "netfront") < 0)
goto cleanup;
if (model) {
if (virDomainNetSetModelString(net, model) < 0)
goto cleanup;
} else {
if (type && STREQ(type, "netfront"))
net->model = VIR_DOMAIN_NET_MODEL_NETFRONT;
}
tmp = sexpr_node(node, "device/vif/rate");
if (tmp) {
@ -1934,7 +1935,7 @@ xenFormatSxprNet(virConnectPtr conn,
virBufferEscapeSexpr(buf, "(model '%s')",
virDomainNetGetModelString(def));
} else {
if (virDomainNetStreqModelString(def, "netfront"))
if (def->model == VIR_DOMAIN_NET_MODEL_NETFRONT)
virBufferAddLit(buf, "(type netfront)");
else
virBufferEscapeSexpr(buf, "(model '%s')",