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", "udp",
); );
VIR_ENUM_IMPL(virDomainNetModel,
VIR_DOMAIN_NET_MODEL_LAST,
"unknown",
"netfront",
);
VIR_ENUM_IMPL(virDomainNetBackend, VIR_ENUM_IMPL(virDomainNetBackend,
VIR_DOMAIN_NET_BACKEND_TYPE_LAST, VIR_DOMAIN_NET_BACKEND_TYPE_LAST,
"default", "default",
@ -2326,6 +2332,7 @@ virDomainNetDefClear(virDomainNetDefPtr def)
return; return;
VIR_FREE(def->modelstr); VIR_FREE(def->modelstr);
def->model = VIR_DOMAIN_NET_MODEL_UNKNOWN;
switch (def->type) { switch (def->type) {
case VIR_DOMAIN_NET_TYPE_VHOSTUSER: case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
@ -11607,20 +11614,9 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
goto error; goto error;
} }
/* NIC model (see -net nic,model=?). We only check that it looks if (model != NULL &&
* reasonable, not that it is a supported NIC type. FWIW kvm virDomainNetSetModelString(def, model) < 0)
* 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; goto error;
}
VIR_STEAL_PTR(def->modelstr, model);
}
switch (def->type) { switch (def->type) {
case VIR_DOMAIN_NET_TYPE_NETWORK: case VIR_DOMAIN_NET_TYPE_NETWORK:
@ -21831,6 +21827,14 @@ virDomainNetDefCheckABIStability(virDomainNetDefPtr src,
return false; 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) { if (src->mtu != dst->mtu) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Target network card MTU %d does not match source %d"), _("Target network card MTU %d does not match source %d"),
@ -29480,6 +29484,8 @@ virDomainNetGetActualTrustGuestRxFilters(virDomainNetDefPtr iface)
const char * const char *
virDomainNetGetModelString(const virDomainNetDef *net) virDomainNetGetModelString(const virDomainNetDef *net)
{ {
if (net->model)
return virDomainNetModelTypeToString(net->model);
return net->modelstr; return net->modelstr;
} }
@ -29487,13 +29493,31 @@ int
virDomainNetSetModelString(virDomainNetDefPtr net, virDomainNetSetModelString(virDomainNetDefPtr net,
const char *model) 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 int
virDomainNetStreqModelString(const virDomainNetDef *net, virDomainNetStreqModelString(const virDomainNetDef *net,
const char *model) const char *model)
{ {
if (net->model)
return net->model == virDomainNetModelTypeFromString(model);
return STREQ_NULLABLE(net->modelstr, model); return STREQ_NULLABLE(net->modelstr, model);
} }
@ -29501,6 +29525,8 @@ int
virDomainNetStrcaseeqModelString(const virDomainNetDef *net, virDomainNetStrcaseeqModelString(const virDomainNetDef *net,
const char *model) const char *model)
{ {
if (net->model)
return STRCASEEQ(virDomainNetModelTypeToString(net->model), model);
return net->modelstr && STRCASEEQ(net->modelstr, model); return net->modelstr && STRCASEEQ(net->modelstr, model);
} }

View File

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

View File

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

View File

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

View File

@ -3799,6 +3799,14 @@ qemuDomainChangeNet(virQEMUDriverPtr driver,
goto cleanup; 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) && if (virDomainNetIsVirtioModel(olddev) &&
(olddev->driver.virtio.name != newdev->driver.virtio.name || (olddev->driver.virtio.name != newdev->driver.virtio.name ||
olddev->driver.virtio.txmode != newdev->driver.virtio.txmode || 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) VIR_STRDUP(net->script, script) < 0)
goto cleanup; goto cleanup;
if (model[0] && if (model[0]) {
virDomainNetSetModelString(net, model) < 0) if (virDomainNetSetModelString(net, model) < 0)
goto cleanup;
if (!model[0] && type[0] && STREQ(type, vif_typename) &&
virDomainNetSetModelString(net, "netfront") < 0)
goto cleanup; goto cleanup;
} else {
if (type[0] && STREQ(type, vif_typename))
net->model = VIR_DOMAIN_NET_MODEL_NETFRONT;
}
if (vifname[0] && if (vifname[0] &&
VIR_STRDUP(net->ifname, vifname) < 0) VIR_STRDUP(net->ifname, vifname) < 0)
@ -1427,7 +1427,7 @@ xenFormatNet(virConnectPtr conn,
virBufferAsprintf(&buf, ",model=%s", virBufferAsprintf(&buf, ",model=%s",
virDomainNetGetModelString(net)); virDomainNetGetModelString(net));
} else { } else {
if (virDomainNetStreqModelString(net, "netfront")) if (net->model == VIR_DOMAIN_NET_MODEL_NETFRONT)
virBufferAsprintf(&buf, ",type=%s", vif_typename); virBufferAsprintf(&buf, ",type=%s", vif_typename);
else else
virBufferAsprintf(&buf, ",model=%s", virBufferAsprintf(&buf, ",model=%s",

View File

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