]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
conf: net: Add model enum, and netfront value
authorCole Robinson <crobinso@redhat.com>
Fri, 18 Jan 2019 00:12:27 +0000 (19:12 -0500)
committerCole Robinson <crobinso@redhat.com>
Tue, 16 Apr 2019 17:11:08 +0000 (13:11 -0400)
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>
src/conf/domain_conf.c
src/conf/domain_conf.h
src/libvirt_private.syms
src/libxl/libxl_conf.c
src/qemu/qemu_hotplug.c
src/xenconfig/xen_common.c
src/xenconfig/xen_sxpr.c

index a0838c14f320a5f52503b6d8f2c9516d83094ebc..f5350430b0877e9de39aef85915a1c105fb1d55e 100644 (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);
 }
 
index c0dfd7434951d6e8128cf9873c2c59ae451e2065..4cb23ed31aa536cb82b138f234bdff14116ba527 100644 (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);
index 62dd518a8ab2952c4e1e7dc900f681ac0ea8bb75..6ccec70749913d518e548f01f26a8e8c42df2ecb 100644 (file)
@@ -478,6 +478,8 @@ virDomainNetGetActualVlan;
 virDomainNetGetModelString;
 virDomainNetInsert;
 virDomainNetIsVirtioModel;
+virDomainNetModelTypeFromString;
+virDomainNetModelTypeToString;
 virDomainNetNotifyActualDevice;
 virDomainNetReleaseActualDevice;
 virDomainNetRemove;
index b3c724acb4116730da5972c67aa6f0693e3990cd..da1fc4f9f2d787ffdb4f723d2f7cc44dc21821c3 100644 (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;
index 069c96180fb58687dfb7b0c331d0ab4efa8e0f19..a4f7d111b119d984e43c37038765768410deac39 100644 (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 ||
index 170378fab5396638cb2c7fe84559da4e877d5d04..69a6f53507613212b6646c65a1141a2cd4b03274 100644 (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",
index 224c874b90a4a88c7e4b9b3a32195bbc4af96dfe..0bff94ead56175688af54d0f1f5dafa522251cdd 100644 (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')",