Co-authored-by: Dawid Zamirski <dzamirski@xxxxxxxxx> Signed-off-by: Matt Coleman <matt@xxxxxxxxx> --- po/POTFILES.in | 1 + src/hyperv/hyperv_driver.c | 2 + src/hyperv/hyperv_network_driver.c | 127 +++++++++++++++++++++++++++++ src/hyperv/hyperv_network_driver.h | 26 ++++++ src/hyperv/meson.build | 1 + 5 files changed, 157 insertions(+) create mode 100644 src/hyperv/hyperv_network_driver.c create mode 100644 src/hyperv/hyperv_network_driver.h diff --git a/po/POTFILES.in b/po/POTFILES.in index b09e58f14a..80c5f145be 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -78,6 +78,7 @@ @SRCDIR@src/esx/esx_vi_methods.c @SRCDIR@src/esx/esx_vi_types.c @SRCDIR@src/hyperv/hyperv_driver.c +@SRCDIR@src/hyperv/hyperv_network_driver.c @SRCDIR@src/hyperv/hyperv_util.c @SRCDIR@src/hyperv/hyperv_wmi.c @SRCDIR@src/hypervisor/domain_cgroup.c diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c index 29908f2e75..c99d2a4e79 100644 --- a/src/hyperv/hyperv_driver.c +++ b/src/hyperv/hyperv_driver.c @@ -31,6 +31,7 @@ #include "viruuid.h" #include "virutil.h" #include "hyperv_driver.h" +#include "hyperv_network_driver.h" #include "hyperv_private.h" #include "hyperv_util.h" #include "hyperv_wmi.h" @@ -3551,6 +3552,7 @@ static virConnectDriver hypervConnectDriver = { .remoteOnly = true, .uriSchemes = (const char *[]){ "hyperv", NULL }, .hypervisorDriver = &hypervHypervisorDriver, + .networkDriver = &hypervNetworkDriver, }; int diff --git a/src/hyperv/hyperv_network_driver.c b/src/hyperv/hyperv_network_driver.c new file mode 100644 index 0000000000..3931e548f5 --- /dev/null +++ b/src/hyperv/hyperv_network_driver.c @@ -0,0 +1,127 @@ +/* + * hyperv_network_driver.c: network driver functions for Microsoft Hyper-V hosts + * + * Copyright (C) 2020 Datto Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#include <config.h> + +#include "datatypes.h" +#include "viralloc.h" +#include "network_conf.h" +#include "hyperv_network_driver.h" +#include "hyperv_wmi.h" + +#define VIR_FROM_THIS VIR_FROM_HYPERV + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Utility functions + */ + +static virNetworkPtr +hypervMsvmVirtualSwitchToNetwork(virConnectPtr conn, Msvm_VirtualEthernetSwitch *virtualSwitch) +{ + unsigned char uuid[VIR_UUID_BUFLEN]; + + if (virUUIDParse(virtualSwitch->data->Name, uuid) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not parse UUID from string '%s'"), + virtualSwitch->data->Name); + return NULL; + } + + return virGetNetwork(conn, virtualSwitch->data->ElementName, uuid); +} + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Exported API functions + */ + +#define MATCH(FLAG) (flags & (FLAG)) +static int +hypervConnectListAllNetworks(virConnectPtr conn, + virNetworkPtr **nets, + unsigned int flags) +{ + int ret = -1; + hypervPrivate *priv = conn->privateData; + size_t count = 0; + size_t i; + g_auto(virBuffer) query = { g_string_new(MSVM_VIRTUALETHERNETSWITCH_WQL_SELECT + "WHERE HealthState = 5"), 0 }; + g_autoptr(Msvm_VirtualEthernetSwitch) switches = NULL; + Msvm_VirtualEthernetSwitch *entry = NULL; + + virCheckFlags(VIR_CONNECT_LIST_NETWORKS_FILTERS_ALL, -1); + + /* + * Hyper-V networks are always active, persistent, and + * autostarted, so return zero elements in case we are asked + * for networks different than that. + */ + if (MATCH(VIR_CONNECT_LIST_NETWORKS_FILTERS_ACTIVE) && + !(MATCH(VIR_CONNECT_LIST_NETWORKS_ACTIVE))) + return 0; + if (MATCH(VIR_CONNECT_LIST_NETWORKS_FILTERS_PERSISTENT) && + !(MATCH(VIR_CONNECT_LIST_NETWORKS_PERSISTENT))) + return 0; + if (MATCH(VIR_CONNECT_LIST_NETWORKS_FILTERS_AUTOSTART) && + !(MATCH(VIR_CONNECT_LIST_NETWORKS_AUTOSTART))) + return 0; + + if (hypervGetWmiClass(Msvm_VirtualEthernetSwitch, &switches) < 0) + goto cleanup; + + for (entry = switches; entry; entry = entry->next) { + if (nets) { + virNetworkPtr net = hypervMsvmVirtualSwitchToNetwork(conn, entry); + if (!net) + goto cleanup; + if (VIR_APPEND_ELEMENT(*nets, count, net) < 0) + goto cleanup; + } else { + ++count; + } + } + + ret = count; + + cleanup: + if (ret < 0 && nets && *nets) { + for (i = 0; i < count; ++i) + VIR_FREE((*nets)[i]); + VIR_FREE(*nets); + } + + return ret; +} +#undef MATCH + + +static int +hypervConnectNumOfNetworks(virConnectPtr conn) +{ + return hypervConnectListAllNetworks(conn, NULL, 0); +} + + +virNetworkDriver hypervNetworkDriver = { + .connectNumOfNetworks = hypervConnectNumOfNetworks, /* 7.1.0 */ + .connectListAllNetworks = hypervConnectListAllNetworks, /* 7.1.0 */ +}; diff --git a/src/hyperv/hyperv_network_driver.h b/src/hyperv/hyperv_network_driver.h new file mode 100644 index 0000000000..16b0621f05 --- /dev/null +++ b/src/hyperv/hyperv_network_driver.h @@ -0,0 +1,26 @@ +/* + * hyperv_network_driver.h: network driver functions for Microsoft Hyper-V hosts + * + * Copyright (C) 2020 Datto Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +#pragma once + +#include "driver.h" + +extern virNetworkDriver hypervNetworkDriver; diff --git a/src/hyperv/meson.build b/src/hyperv/meson.build index 1020e3d6b0..0f0cdb9e54 100644 --- a/src/hyperv/meson.build +++ b/src/hyperv/meson.build @@ -1,5 +1,6 @@ hyperv_sources = [ 'hyperv_driver.c', + 'hyperv_network_driver.c', 'hyperv_util.c', 'hyperv_wmi.c', 'hyperv_wmi_classes.c', -- 2.30.0