]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
bhyve: support interface type 'network'
authorRoman Bogorodskiy <bogorodskiy@gmail.com>
Tue, 1 Apr 2025 17:32:34 +0000 (19:32 +0200)
committerRoman Bogorodskiy <bogorodskiy@gmail.com>
Thu, 10 Apr 2025 13:14:54 +0000 (15:14 +0200)
Add support for interface type 'network'. While bridge remains the only
supported options for networks in bhyve, supporting interface type
'network' allows easier configuration and makes domain XMLs more
compatible with the other drivers.

While here, update the error message for the unsupported interface type
to print the requested network type string instead of an integer to make
it more user-friendly.

Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
src/bhyve/bhyve_command.c
src/bhyve/bhyve_process.c

index 50de3e166072188cd41d7bcb16fe2607cbfb1285..b9f4a152007fa17565ebfdea4bbecc0a2929b571 100644 (file)
@@ -27,6 +27,7 @@
 #include "bhyve_domain.h"
 #include "bhyve_conf.h"
 #include "bhyve_driver.h"
+#include "domain_validate.h"
 #include "datatypes.h"
 #include "viralloc.h"
 #include "virfile.h"
@@ -41,7 +42,7 @@
 VIR_LOG_INIT("bhyve.bhyve_command");
 
 static int
-bhyveBuildNetArgStr(const virDomainDef *def,
+bhyveBuildNetArgStr(virDomainDef *def,
                     virDomainNetDef *net,
                     struct _bhyveConn *driver,
                     virCommand *cmd,
@@ -53,6 +54,7 @@ bhyveBuildNetArgStr(const virDomainDef *def,
     char *nic_model = NULL;
     int ret = -1;
     virDomainNetType actualType = virDomainNetGetActualType(net);
+    g_autoptr(virConnect) netconn = NULL;
 
     if (net->model == VIR_DOMAIN_NET_MODEL_VIRTIO) {
         nic_model = g_strdup("virtio-net");
@@ -70,12 +72,43 @@ bhyveBuildNetArgStr(const virDomainDef *def,
         return -1;
     }
 
-    if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) {
+    if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
+        if (!netconn && !(netconn = virGetConnectNetwork()))
+            goto cleanup;
+        if (virDomainNetAllocateActualDevice(netconn, def, net) < 0)
+            goto cleanup;
+    }
+    /* final validation now that actual type is known */
+    if (virDomainActualNetDefValidate(net) < 0)
+        return -1;
+
+    switch (actualType) {
+    case VIR_DOMAIN_NET_TYPE_NETWORK:
+    case VIR_DOMAIN_NET_TYPE_BRIDGE:
         brname = g_strdup(virDomainNetGetActualBridgeName(net));
-    } else {
+        if (!brname) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("No bridge name specified"));
+            goto cleanup;
+        }
+        break;
+    case VIR_DOMAIN_NET_TYPE_ETHERNET:
+    case VIR_DOMAIN_NET_TYPE_DIRECT:
+    case VIR_DOMAIN_NET_TYPE_USER:
+    case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
+    case VIR_DOMAIN_NET_TYPE_SERVER:
+    case VIR_DOMAIN_NET_TYPE_CLIENT:
+    case VIR_DOMAIN_NET_TYPE_MCAST:
+    case VIR_DOMAIN_NET_TYPE_UDP:
+    case VIR_DOMAIN_NET_TYPE_INTERNAL:
+    case VIR_DOMAIN_NET_TYPE_HOSTDEV:
+    case VIR_DOMAIN_NET_TYPE_VDPA:
+    case VIR_DOMAIN_NET_TYPE_NULL:
+    case VIR_DOMAIN_NET_TYPE_VDS:
+    case VIR_DOMAIN_NET_TYPE_LAST:
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                       _("Network type %1$d is not supported"),
-                       virDomainNetGetActualType(net));
+                       _("Unsupported network type %1$s"),
+                       virDomainNetTypeToString(actualType));
         goto cleanup;
     }
 
index 3e6f678cf5d1d19aa90163b1617f4f49d3a82182..a17994e2a07acd3713acdc9995fe50854bcfdf96 100644 (file)
@@ -2,6 +2,7 @@
  * bhyve_process.c: bhyve process management
  *
  * Copyright (C) 2014 Roman Bogorodskiy
+ * Copyright (C) 2025 The FreeBSD Foundation
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -71,18 +72,23 @@ static void
 bhyveNetCleanup(virDomainObj *vm)
 {
     size_t i;
+    g_autoptr(virConnect) conn = NULL;
 
     for (i = 0; i < vm->def->nnets; i++) {
         virDomainNetDef *net = vm->def->nets[i];
         virDomainNetType actualType = virDomainNetGetActualType(net);
 
-        if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) {
-            if (net->ifname) {
-                ignore_value(virNetDevBridgeRemovePort(
-                                virDomainNetGetActualBridgeName(net),
-                                net->ifname));
-                ignore_value(virNetDevTapDelete(net->ifname, NULL));
-            }
+        if (net->ifname) {
+            ignore_value(virNetDevBridgeRemovePort(
+                             virDomainNetGetActualBridgeName(net),
+                             net->ifname));
+            ignore_value(virNetDevTapDelete(net->ifname, NULL));
+        }
+        if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK) {
+            if (conn || (conn = virGetConnectNetwork()))
+                virDomainNetReleaseActualDevice(conn, net);
+            else
+                VIR_WARN("Unable to release network device '%s'", NULLSTR(net->ifname));
         }
     }
 }
@@ -437,6 +443,8 @@ virBhyveProcessReconnect(virDomainObj *vm,
     char **proc_argv;
     char *expected_proctitle = NULL;
     bhyveDomainObjPrivate *priv = vm->privateData;
+    g_autoptr(virConnect) conn = NULL;
+    size_t i;
     int ret = -1;
 
     if (!virDomainObjIsActive(vm))
@@ -469,6 +477,14 @@ virBhyveProcessReconnect(virDomainObj *vm,
          }
     }
 
+    for (i = 0; i < vm->def->nnets; i++) {
+        virDomainNetDef *net = vm->def->nets[i];
+        if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK && !conn)
+            conn = virGetConnectNetwork();
+
+        virDomainNetNotifyActualDevice(conn, vm->def, net);
+    }
+
  cleanup:
     if (ret < 0) {
         /* If VM is reported to be in active state, but we cannot find