diff --git a/src/bhyve/bhyve_capabilities.c b/src/bhyve/bhyve_capabilities.c
index 83e3ae1b4bbdc22b5b22d6985fdf3171c91fc966..1dc0593aff00ad785640a7863982ee8c85ff93ba 100644
--- a/src/bhyve/bhyve_capabilities.c
+++ b/src/bhyve/bhyve_capabilities.c
@@ -216,6 +216,28 @@ bhyveProbeCapsAHCI32Slot(unsigned int *caps, char *binary)
return ret;
}
+static int
+bhyveProbeCapsNetE1000(unsigned int *caps, char *binary)
+{
+ char *error;
+ virCommandPtr cmd = NULL;
+ int ret = -1, exit;
+
+ cmd = virCommandNew(binary);
+ virCommandAddArgList(cmd, "-s", "0,e1000", NULL);
+ virCommandSetErrorBuffer(cmd, &error);
+ if (virCommandRun(cmd, &exit) < 0)
+ goto cleanup;
+
+ if (strstr(error, "pci slot 0:0: unknown device \"e1000\"") == NULL)
+ *caps |= BHYVE_CAP_NET_E1000;
+
+ ret = 0;
+ cleanup:
+ VIR_FREE(error);
+ virCommandFree(cmd);
+ return ret;
+}
int
virBhyveProbeCaps(unsigned int *caps)
@@ -235,6 +257,9 @@ virBhyveProbeCaps(unsigned int *caps)
if ((ret = bhyveProbeCapsAHCI32Slot(caps, binary)))
goto out;
+ if ((ret = bhyveProbeCapsNetE1000(caps, binary)))
+ goto out;
+
out:
VIR_FREE(binary);
return ret;
diff --git a/src/bhyve/bhyve_capabilities.h b/src/bhyve/bhyve_capabilities.h
index 55581bd682f93e3b87173f6380e245f9c77855bc..690feadb84a7409bc02172e8dea3fb26b6f160f5 100644
--- a/src/bhyve/bhyve_capabilities.h
+++ b/src/bhyve/bhyve_capabilities.h
@@ -39,6 +39,7 @@ typedef enum {
typedef enum {
BHYVE_CAP_RTC_UTC = 1 << 0,
BHYVE_CAP_AHCI32SLOT = 1 << 1,
+ BHYVE_CAP_NET_E1000 = 1 << 2,
} virBhyveCapsFlags;
int virBhyveProbeGrubCaps(virBhyveGrubCapsFlags *caps);
diff --git a/src/bhyve/bhyve_command.c b/src/bhyve/bhyve_command.c
index 192a9220c13c0ab2347c203cfe3d0fdbd1dc003b..e7131625c9bf2cfe9af99715c712b250583f4dd1 100644
--- a/src/bhyve/bhyve_command.c
+++ b/src/bhyve/bhyve_command.c
@@ -44,7 +44,8 @@
VIR_LOG_INIT("bhyve.bhyve_command");
static int
-bhyveBuildNetArgStr(const virDomainDef *def,
+bhyveBuildNetArgStr(virConnectPtr conn,
+ const virDomainDef *def,
virDomainNetDefPtr net,
virCommandPtr cmd,
bool dryRun)
@@ -52,9 +53,30 @@ bhyveBuildNetArgStr(const virDomainDef *def,
char macaddr[VIR_MAC_STRING_BUFLEN];
char *realifname = NULL;
char *brname = NULL;
+ char *nic_model = NULL;
int ret = -1;
virDomainNetType actualType = virDomainNetGetActualType(net);
+ if (STREQ(net->model, "virtio")) {
+ if (VIR_STRDUP(nic_model, "virtio-net") < 0)
+ return -1;
+ } else if (STREQ(net->model, "e1000")) {
+ if ((bhyveDriverGetCaps(conn) & BHYVE_CAP_NET_E1000) != 0) {
+ if (VIR_STRDUP(nic_model, "e1000") < 0)
+ return -1;
+ } else {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("NIC model 'e1000' is not supported "
+ "by given bhyve binary"));
+ return -1;
+ }
+ } else {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("NIC model '%s' is not supported"),
+ net->model);
+ return -1;
+ }
+
if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) {
if (VIR_STRDUP(brname, virDomainNetGetActualBridgeName(net)) < 0)
goto cleanup;
@@ -102,8 +124,8 @@ bhyveBuildNetArgStr(const virDomainDef *def,
virCommandAddArg(cmd, "-s");
- virCommandAddArgFormat(cmd, "%d:0,virtio-net,%s,mac=%s",
- net->info.addr.pci.slot,
+ virCommandAddArgFormat(cmd, "%d:0,%s,%s,mac=%s",
+ net->info.addr.pci.slot, nic_model,
realifname, virMacAddrFormat(&net->mac, macaddr));
ret = 0;
@@ -112,6 +134,7 @@ bhyveBuildNetArgStr(const virDomainDef *def,
VIR_FREE(net->ifname);
VIR_FREE(brname);
VIR_FREE(realifname);
+ VIR_FREE(nic_model);
return ret;
}
@@ -346,7 +369,7 @@ virBhyveProcessBuildBhyveCmd(virConnectPtr conn,
}
for (i = 0; i < def->nnets; i++) {
virDomainNetDefPtr net = def->nets[i];
- if (bhyveBuildNetArgStr(def, net, cmd, dryRun) < 0)
+ if (bhyveBuildNetArgStr(conn, def, net, cmd, dryRun) < 0)
goto error;
}
for (i = 0; i < def->ndisks; i++) {
diff --git a/src/bhyve/bhyve_parse_command.c b/src/bhyve/bhyve_parse_command.c
index e31f5fbd143890cffadf023da8118a09e0802606..fcaaed2759bfb30565db29aa9b7df1ca3dc5c796 100644
--- a/src/bhyve/bhyve_parse_command.c
+++ b/src/bhyve/bhyve_parse_command.c
@@ -496,6 +496,7 @@ bhyveParsePCINet(virDomainDefPtr def,
unsigned pcislot,
unsigned pcibus,
unsigned function,
+ const char *model,
const char *config)
{
/* -s slot,virtio-net,tapN[,mac=xx:xx:xx:xx:xx:xx] */
@@ -514,6 +515,9 @@ bhyveParsePCINet(virDomainDefPtr def,
if (VIR_STRDUP(net->data.bridge.brname, "virbr0") < 0)
goto error;
+ if (VIR_STRDUP(net->model, model) < 0)
+ goto error;
+
net->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
net->info.addr.pci.slot = pcislot;
net->info.addr.pci.bus = pcibus;
@@ -620,7 +624,11 @@ bhyveParseBhyvePCIArg(virDomainDefPtr def,
nahcidisk,
conf);
else if (STREQ(emulation, "virtio-net"))
- bhyveParsePCINet(def, xmlopt, caps, pcislot, bus, function, conf);
+ bhyveParsePCINet(def, xmlopt, caps, pcislot, bus, function,
+ "virtio", conf);
+ else if (STREQ(emulation, "e1000"))
+ bhyveParsePCINet(def, xmlopt, caps, pcislot, bus, function,
+ "e1000", conf);
VIR_FREE(emulation);
VIR_FREE(slotdef);
diff --git a/tests/bhyveargv2xmldata/bhyveargv2xml-e1000.args b/tests/bhyveargv2xmldata/bhyveargv2xml-e1000.args
new file mode 100644
index 0000000000000000000000000000000000000000..aa568fe3aa7f394cf9261d65b86d40f12a857cdc
--- /dev/null
+++ b/tests/bhyveargv2xmldata/bhyveargv2xml-e1000.args
@@ -0,0 +1,8 @@
+/usr/sbin/bhyve \
+-c 1 \
+-m 214 \
+-H \
+-P \
+-s 0:0,hostbridge \
+-s 1:0,e1000,tap0 \
+-s 1:1,e1000,tap1,mac=FE:ED:AD:EA:DF:15 bhyve
diff --git a/tests/bhyveargv2xmldata/bhyveargv2xml-e1000.xml b/tests/bhyveargv2xmldata/bhyveargv2xml-e1000.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c6b6c0ef82d2a4e5c7f74480bcc89fef1eea7fe2
--- /dev/null
+++ b/tests/bhyveargv2xmldata/bhyveargv2xml-e1000.xml
@@ -0,0 +1,30 @@
+