[libvirt] [PATCH] apparmor: Add openGraphicsFD rule for named profile
by Christian Ehrhardt
Commit a3ab6d42 changed the libvirtd profile to a named profile
but neglected to accommodate the change in the qemu profile
ptrace and signal rules.
Later on 4ec3cf9a fixed that for ptrace and signal but openGraphicsFD
is still missing.
As a result, libvirtd is unable to open UI on libvirt >=5.1 e.g. with
virt-manager.
Add openGraphicsFD rule that references the libvirtd profile
by name in addition to full binary path.
Fixes: https://bugs.launchpad.net/ubuntu/+source/libvirt/+bug/1833040
Signed-off-by: Christian Ehrhardt <christian.ehrhardt(a)canonical.com>
---
src/security/apparmor/libvirt-qemu | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/security/apparmor/libvirt-qemu b/src/security/apparmor/libvirt-qemu
index 165558fe83..d33348aa05 100644
--- a/src/security/apparmor/libvirt-qemu
+++ b/src/security/apparmor/libvirt-qemu
@@ -208,6 +208,7 @@
/sys/firmware/devicetree/** r,
# allow connect with openGraphicsFD to work
+ unix (send, receive) type=stream addr=none peer=(label=libvirtd),
unix (send, receive) type=stream addr=none peer=(label=/usr/sbin/libvirtd),
# for gathering information about available host resources
--
2.21.0
5 years, 6 months
[libvirt] [PATCH] remote: use VIR_DRV_OPEN_REMOTE_USER in ssh transport checks
by Daniel P. Berrangé
We currently refuse to connect to remote libvirtd over SSH if we see the
path ends in /session. Earlier on though we checked for /session and set
the VIR_DRV_OPEN_REMOTE_USER flag. There is one subtle distinction
though with the test driver. All test URIs are marked with this flag,
regardless of whether the URI indicates a local or remote connection.
Previously a local connection to the test driver would have used the
unprivileged libvirtd while a remote connection would have tried the
privileged libvirtd. With this we are consistent and use the
unprivileged for both local & remote, if the current user is non-root.
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
src/remote/remote_driver.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 0a37a63e8d..e1eaa56230 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -1002,7 +1002,7 @@ doRemoteOpen(virConnectPtr conn,
case trans_libssh2:
if (!sockname) {
/* Right now we don't support default session connections */
- if (STREQ_NULLABLE(conn->uri->path, "/session")) {
+ if (flags & VIR_DRV_OPEN_REMOTE_USER) {
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
_("Connecting to session instance without "
"socket path is not supported by the libssh2 "
@@ -1037,7 +1037,7 @@ doRemoteOpen(virConnectPtr conn,
case trans_libssh:
if (!sockname) {
/* Right now we don't support default session connections */
- if (STREQ_NULLABLE(conn->uri->path, "/session")) {
+ if (flags & VIR_DRV_OPEN_REMOTE_USER) {
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
_("Connecting to session instance without "
"socket path is not supported by the libssh "
@@ -1103,7 +1103,7 @@ doRemoteOpen(virConnectPtr conn,
if (!sockname) {
/* Right now we don't support default session connections */
- if (STREQ_NULLABLE(conn->uri->path, "/session")) {
+ if (flags & VIR_DRV_OPEN_REMOTE_USER) {
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
_("Connecting to session instance without "
"socket path is not supported by the ssh "
--
2.21.0
5 years, 6 months
[libvirt] [PATCH] remote: remove obsolete & incorrect comment from libvirtd.conf
by Daniel P. Berrangé
The libvirtd.conf file has a comment pointing people to format.html
which has nothing todo with the configuration file format.
It also has a comment about tests/daemon-conf which no longer exists,
and even if it did exist such comment is not relevant to end users
when this file is installed in /etc/.
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
src/remote/libvirtd.conf | 5 -----
1 file changed, 5 deletions(-)
diff --git a/src/remote/libvirtd.conf b/src/remote/libvirtd.conf
index ac07df6930..233c127156 100644
--- a/src/remote/libvirtd.conf
+++ b/src/remote/libvirtd.conf
@@ -1,10 +1,5 @@
# Master libvirt daemon configuration file
#
-# For further information consult https://libvirt.org/format.html
-#
-# NOTE: the tests/daemon-conf regression test script requires
-# that each "PARAMETER = VALUE" line in this file have the parameter
-# name just after a leading "#".
#################################################################
#
--
2.21.0
5 years, 6 months
[libvirt] [go PATCH] Add support for virNetworkPort object and APIs
by Daniel P. Berrangé
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
network.go | 80 ++++++++++++++
network_port.go | 233 ++++++++++++++++++++++++++++++++++++++++
network_port_compat.h | 67 ++++++++++++
network_port_wrapper.go | 197 +++++++++++++++++++++++++++++++++
network_port_wrapper.h | 79 ++++++++++++++
network_wrapper.go | 73 +++++++++++++
network_wrapper.h | 23 ++++
7 files changed, 752 insertions(+)
create mode 100644 network_port.go
create mode 100644 network_port_compat.h
create mode 100644 network_port_wrapper.go
create mode 100644 network_port_wrapper.h
diff --git a/network.go b/network.go
index 99954aa..a0bc361 100644
--- a/network.go
+++ b/network.go
@@ -34,6 +34,7 @@ package libvirt
import "C"
import (
+ "fmt"
"reflect"
"time"
"unsafe"
@@ -333,3 +334,82 @@ func (n *Network) GetDHCPLeases() ([]NetworkDHCPLease, error) {
C.free(unsafe.Pointer(cLeases))
return leases, nil
}
+
+// See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkPortLooku...
+func (n *Network) LookupNetworkPortByUUIDString(uuid string) (*NetworkPort, error) {
+ if C.LIBVIR_VERSION_NUMBER < 5005000 {
+ return nil, makeNotImplementedError("virNetworkPortLookupByUUIDString")
+ }
+
+ cUuid := C.CString(uuid)
+ defer C.free(unsafe.Pointer(cUuid))
+ var err C.virError
+ ptr := C.virNetworkPortLookupByUUIDStringWrapper(n.ptr, cUuid, &err)
+ if ptr == nil {
+ return nil, makeError(&err)
+ }
+ return &NetworkPort{ptr: ptr}, nil
+}
+
+// See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkPortLooku...
+func (n *Network) LookupNetworkPortByUUID(uuid []byte) (*NetworkPort, error) {
+ if C.LIBVIR_VERSION_NUMBER < 5005000 {
+ return nil, makeNotImplementedError("virNetworkPortLookupByUUID")
+ }
+
+ if len(uuid) != C.VIR_UUID_BUFLEN {
+ return nil, fmt.Errorf("UUID must be exactly %d bytes in size",
+ int(C.VIR_UUID_BUFLEN))
+ }
+ cUuid := make([]C.uchar, C.VIR_UUID_BUFLEN)
+ for i := 0; i < C.VIR_UUID_BUFLEN; i++ {
+ cUuid[i] = C.uchar(uuid[i])
+ }
+ var err C.virError
+ ptr := C.virNetworkPortLookupByUUIDWrapper(n.ptr, &cUuid[0], &err)
+ if ptr == nil {
+ return nil, makeError(&err)
+ }
+ return &NetworkPort{ptr: ptr}, nil
+}
+
+// See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkPortCreat...
+func (n *Network) PortCreateXML(xmlConfig string, flags uint) (*NetworkPort, error) {
+ if C.LIBVIR_VERSION_NUMBER < 5005000 {
+ return nil, makeNotImplementedError("virNetworkPortCreateXML")
+ }
+ cXml := C.CString(string(xmlConfig))
+ defer C.free(unsafe.Pointer(cXml))
+ var err C.virError
+ ptr := C.virNetworkPortCreateXMLWrapper(n.ptr, cXml, C.uint(flags), &err)
+ if ptr == nil {
+ return nil, makeError(&err)
+ }
+ return &NetworkPort{ptr: ptr}, nil
+}
+
+// See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkListAllPorts
+func (n *Network) ListAllPorts(flags uint) ([]NetworkPort, error) {
+ if C.LIBVIR_VERSION_NUMBER < 5005000 {
+ return []NetworkPort{}, makeNotImplementedError("virNetworkListAllPorts")
+ }
+
+ var cList *C.virNetworkPortPtr
+ var err C.virError
+ numPorts := C.virNetworkListAllPortsWrapper(n.ptr, (**C.virNetworkPortPtr)(&cList), C.uint(flags), &err)
+ if numPorts == -1 {
+ return []NetworkPort{}, makeError(&err)
+ }
+ hdr := reflect.SliceHeader{
+ Data: uintptr(unsafe.Pointer(cList)),
+ Len: int(numPorts),
+ Cap: int(numPorts),
+ }
+ var ports []NetworkPort
+ slice := *(*[]C.virNetworkPortPtr)(unsafe.Pointer(&hdr))
+ for _, ptr := range slice {
+ ports = append(ports, NetworkPort{ptr})
+ }
+ C.free(unsafe.Pointer(cList))
+ return ports, nil
+}
diff --git a/network_port.go b/network_port.go
new file mode 100644
index 0000000..e701c2d
--- /dev/null
+++ b/network_port.go
@@ -0,0 +1,233 @@
+/*
+ * This file is part of the libvirt-go project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * Copyright (C) 2019 Red Hat, Inc.
+ *
+ */
+
+package libvirt
+
+/*
+#cgo pkg-config: libvirt
+#include <stdlib.h>
+#include "network_port_wrapper.h"
+*/
+import "C"
+
+import (
+ "unsafe"
+)
+
+type NetworkPortCreateFlags int
+
+const (
+ NETWORK_PORT_CREATE_RECLAIM = NetworkPortCreateFlags(C.VIR_NETWORK_PORT_CREATE_RECLAIM)
+)
+
+type NetworkPort struct {
+ ptr C.virNetworkPortPtr
+}
+
+// See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkPortFree
+func (n *NetworkPort) Free() error {
+ if C.LIBVIR_VERSION_NUMBER < 5005000 {
+ return makeNotImplementedError("virNetworkPortFree")
+ }
+
+ var err C.virError
+ ret := C.virNetworkPortFreeWrapper(n.ptr, &err)
+ if ret == -1 {
+ return makeError(&err)
+ }
+ return nil
+}
+
+// See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkPortRef
+func (c *NetworkPort) Ref() error {
+ if C.LIBVIR_VERSION_NUMBER < 5005000 {
+ return makeNotImplementedError("virNetworkPortRef")
+ }
+
+ var err C.virError
+ ret := C.virNetworkPortRefWrapper(c.ptr, &err)
+ if ret == -1 {
+ return makeError(&err)
+ }
+ return nil
+}
+
+// See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkPortGetUUID
+func (n *NetworkPort) GetUUID() ([]byte, error) {
+ if C.LIBVIR_VERSION_NUMBER < 5005000 {
+ return []byte{}, makeNotImplementedError("virNetworkPortGetUUID")
+ }
+
+ var cUuid [C.VIR_UUID_BUFLEN](byte)
+ cuidPtr := unsafe.Pointer(&cUuid)
+ var err C.virError
+ result := C.virNetworkPortGetUUIDWrapper(n.ptr, (*C.uchar)(cuidPtr), &err)
+ if result != 0 {
+ return []byte{}, makeError(&err)
+ }
+ return C.GoBytes(cuidPtr, C.VIR_UUID_BUFLEN), nil
+}
+
+// See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkPortGetUU...
+func (n *NetworkPort) GetUUIDString() (string, error) {
+ if C.LIBVIR_VERSION_NUMBER < 5005000 {
+ return "", makeNotImplementedError("virNetworkPortGetUUIDString")
+ }
+
+ var cUuid [C.VIR_UUID_STRING_BUFLEN](C.char)
+ cuidPtr := unsafe.Pointer(&cUuid)
+ var err C.virError
+ result := C.virNetworkPortGetUUIDStringWrapper(n.ptr, (*C.char)(cuidPtr), &err)
+ if result != 0 {
+ return "", makeError(&err)
+ }
+ return C.GoString((*C.char)(cuidPtr)), nil
+}
+
+// See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkPortDelete
+func (n *NetworkPort) Delete(flags uint) error {
+ if C.LIBVIR_VERSION_NUMBER < 5005000 {
+ return makeNotImplementedError("virNetworkPortDelete")
+ }
+
+ var err C.virError
+ result := C.virNetworkPortDeleteWrapper(n.ptr, C.uint(flags), &err)
+ if result == -1 {
+ return makeError(&err)
+ }
+ return nil
+}
+
+// See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkPortGetXM...
+func (d *NetworkPort) GetXMLDesc(flags uint) (string, error) {
+ var err C.virError
+ result := C.virNetworkPortGetXMLDescWrapper(d.ptr, C.uint(flags), &err)
+ if result == nil {
+ return "", makeError(&err)
+ }
+ xml := C.GoString(result)
+ C.free(unsafe.Pointer(result))
+ return xml, nil
+}
+
+type NetworkPortParameters struct {
+ BandwidthInAverageSet bool
+ BandwidthInAverage uint
+ BandwidthInPeakSet bool
+ BandwidthInPeak uint
+ BandwidthInBurstSet bool
+ BandwidthInBurst uint
+ BandwidthInFloorSet bool
+ BandwidthInFloor uint
+ BandwidthOutAverageSet bool
+ BandwidthOutAverage uint
+ BandwidthOutPeakSet bool
+ BandwidthOutPeak uint
+ BandwidthOutBurstSet bool
+ BandwidthOutBurst uint
+}
+
+func getNetworkPortParametersFieldInfo(params *NetworkPortParameters) map[string]typedParamsFieldInfo {
+ return map[string]typedParamsFieldInfo{
+ C.VIR_NETWORK_PORT_BANDWIDTH_IN_AVERAGE: typedParamsFieldInfo{
+ set: ¶ms.BandwidthInAverageSet,
+ ui: ¶ms.BandwidthInAverage,
+ },
+ C.VIR_NETWORK_PORT_BANDWIDTH_IN_PEAK: typedParamsFieldInfo{
+ set: ¶ms.BandwidthInPeakSet,
+ ui: ¶ms.BandwidthInPeak,
+ },
+ C.VIR_NETWORK_PORT_BANDWIDTH_IN_BURST: typedParamsFieldInfo{
+ set: ¶ms.BandwidthInBurstSet,
+ ui: ¶ms.BandwidthInBurst,
+ },
+ C.VIR_NETWORK_PORT_BANDWIDTH_IN_FLOOR: typedParamsFieldInfo{
+ set: ¶ms.BandwidthInFloorSet,
+ ui: ¶ms.BandwidthInFloor,
+ },
+ C.VIR_NETWORK_PORT_BANDWIDTH_OUT_AVERAGE: typedParamsFieldInfo{
+ set: ¶ms.BandwidthOutAverageSet,
+ ui: ¶ms.BandwidthOutAverage,
+ },
+ C.VIR_NETWORK_PORT_BANDWIDTH_OUT_PEAK: typedParamsFieldInfo{
+ set: ¶ms.BandwidthOutPeakSet,
+ ui: ¶ms.BandwidthOutPeak,
+ },
+ C.VIR_NETWORK_PORT_BANDWIDTH_OUT_BURST: typedParamsFieldInfo{
+ set: ¶ms.BandwidthOutBurstSet,
+ ui: ¶ms.BandwidthOutBurst,
+ },
+ }
+}
+
+// See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkPortGetPa...
+func (d *NetworkPort) GetParameters(flags uint) (*NetworkPortParameters, error) {
+ if C.LIBVIR_VERSION_NUMBER < 5005000 {
+ return nil, makeNotImplementedError("virNetworkPortGetParameters")
+ }
+
+ params := &NetworkPortParameters{}
+ info := getNetworkPortParametersFieldInfo(params)
+
+ var cparams C.virTypedParameterPtr
+ var cnparams C.int
+ var err C.virError
+ ret := C.virNetworkPortGetParametersWrapper(d.ptr, &cparams, &cnparams, C.uint(flags), &err)
+ if ret == -1 {
+ return nil, makeError(&err)
+ }
+
+ defer C.virTypedParamsFree(cparams, cnparams)
+
+ _, gerr := typedParamsUnpack(cparams, cnparams, info)
+ if gerr != nil {
+ return nil, gerr
+ }
+
+ return params, nil
+}
+
+// See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkPortSetPa...
+func (d *NetworkPort) SetParameters(params *NetworkPortParameters, flags uint) error {
+ if C.LIBVIR_VERSION_NUMBER < 5005000 {
+ return makeNotImplementedError("virNetworkPortSetParameters")
+ }
+
+ info := getNetworkPortParametersFieldInfo(params)
+
+ cparams, cnparams, gerr := typedParamsPackNew(info)
+ if gerr != nil {
+ return gerr
+ }
+ defer C.virTypedParamsFree(cparams, cnparams)
+
+ var err C.virError
+ ret := C.virNetworkPortSetParametersWrapper(d.ptr, cparams, cnparams, C.uint(flags), &err)
+ if ret == -1 {
+ return makeError(&err)
+ }
+
+ return nil
+}
diff --git a/network_port_compat.h b/network_port_compat.h
new file mode 100644
index 0000000..77f541b
--- /dev/null
+++ b/network_port_compat.h
@@ -0,0 +1,67 @@
+/*
+ * This file is part of the libvirt-go project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * Copyright (C) 2019 Red Hat, Inc.
+ *
+ */
+
+#ifndef LIBVIRT_GO_NETWORK_PORT_COMPAT_H__
+#define LIBVIRT_GO_NETWORK_PORT_COMPAT_H__
+
+/* 5.5.0 */
+
+#if LIBVIR_VERSION_NUMBER < 5005000
+typedef struct _virNetworkPort *virNetworkPortPtr;
+#endif
+
+#ifndef VIR_NETWORK_PORT_CREATE_RECLAIM
+#define VIR_NETWORK_PORT_CREATE_RECLAIM (1 << 0)
+#endif
+
+#ifndef VIR_NETWORK_PORT_BANDWIDTH_IN_AVERAGE
+#define VIR_NETWORK_PORT_BANDWIDTH_IN_AVERAGE "inbound.average"
+#endif
+
+#ifndef VIR_NETWORK_PORT_BANDWIDTH_IN_PEAK
+#define VIR_NETWORK_PORT_BANDWIDTH_IN_PEAK "inbound.peak"
+#endif
+
+#ifndef VIR_NETWORK_PORT_BANDWIDTH_IN_BURST
+#define VIR_NETWORK_PORT_BANDWIDTH_IN_BURST "inbound.burst"
+#endif
+
+#ifndef VIR_NETWORK_PORT_BANDWIDTH_IN_FLOOR
+#define VIR_NETWORK_PORT_BANDWIDTH_IN_FLOOR "inbound.floor"
+#endif
+
+#ifndef VIR_NETWORK_PORT_BANDWIDTH_OUT_AVERAGE
+#define VIR_NETWORK_PORT_BANDWIDTH_OUT_AVERAGE "outbound.average"
+#endif
+
+#ifndef VIR_NETWORK_PORT_BANDWIDTH_OUT_PEAK
+#define VIR_NETWORK_PORT_BANDWIDTH_OUT_PEAK "outbound.peak"
+#endif
+
+#ifndef VIR_NETWORK_PORT_BANDWIDTH_OUT_BURST
+#define VIR_NETWORK_PORT_BANDWIDTH_OUT_BURST "outbound.burst"
+#endif
+
+#endif /* LIBVIRT_GO_NETWORK_PORT_COMPAT_H__ */
diff --git a/network_port_wrapper.go b/network_port_wrapper.go
new file mode 100644
index 0000000..2b69167
--- /dev/null
+++ b/network_port_wrapper.go
@@ -0,0 +1,197 @@
+/*
+ * This file is part of the libvirt-go project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * Copyright (C) 2019 Red Hat, Inc.
+ *
+ */
+
+package libvirt
+
+/*
+#cgo pkg-config: libvirt
+#include <assert.h>
+#include "network_port_wrapper.h"
+
+virNetworkPtr
+virNetworkPortGetNetworkWrapper(virNetworkPortPtr port,
+ virErrorPtr err)
+{
+#if LIBVIR_VERSION_NUMBER < 5005000
+ assert(0); // Caller should have checked version
+#else
+ virNetworkPtr ret;
+ ret = virNetworkPortGetNetwork(port);
+ if (!ret) {
+ virCopyLastError(err);
+ }
+ return ret;
+#endif
+}
+
+
+char *
+virNetworkPortGetXMLDescWrapper(virNetworkPortPtr port,
+ unsigned int flags,
+ virErrorPtr err)
+{
+#if LIBVIR_VERSION_NUMBER < 5005000
+ assert(0); // Caller should have checked version
+#else
+ char *ret;
+ ret = virNetworkPortGetXMLDesc(port, flags);
+ if (!ret) {
+ virCopyLastError(err);
+ }
+ return ret;
+#endif
+}
+
+
+int
+virNetworkPortGetUUIDWrapper(virNetworkPortPtr port,
+ unsigned char *uuid,
+ virErrorPtr err)
+{
+#if LIBVIR_VERSION_NUMBER < 5005000
+ assert(0); // Caller should have checked version
+#else
+ int ret;
+ ret = virNetworkPortGetUUID(port, uuid);
+ if (ret < 0) {
+ virCopyLastError(err);
+ }
+ return ret;
+#endif
+}
+
+
+int
+virNetworkPortGetUUIDStringWrapper(virNetworkPortPtr port,
+ char *buf,
+ virErrorPtr err)
+{
+#if LIBVIR_VERSION_NUMBER < 5005000
+ assert(0); // Caller should have checked version
+#else
+ int ret;
+ ret = virNetworkPortGetUUIDString(port, buf);
+ if (ret < 0) {
+ virCopyLastError(err);
+ }
+ return ret;
+#endif
+}
+
+
+int
+virNetworkPortSetParametersWrapper(virNetworkPortPtr port,
+ virTypedParameterPtr params,
+ int nparams,
+ unsigned int flags,
+ virErrorPtr err)
+{
+#if LIBVIR_VERSION_NUMBER < 5005000
+ assert(0); // Caller should have checked version
+#else
+ int ret;
+ ret = virNetworkPortSetParameters(port, params, nparams, flags);
+ if (ret < 0) {
+ virCopyLastError(err);
+ }
+ return ret;
+#endif
+}
+
+
+int
+virNetworkPortGetParametersWrapper(virNetworkPortPtr port,
+ virTypedParameterPtr *params,
+ int *nparams,
+ unsigned int flags,
+ virErrorPtr err)
+{
+#if LIBVIR_VERSION_NUMBER < 5005000
+ assert(0); // Caller should have checked version
+#else
+ int ret;
+ ret = virNetworkPortGetParameters(port, params, nparams, flags);
+ if (ret < 0) {
+ virCopyLastError(err);
+ }
+ return ret;
+#endif
+}
+
+
+int
+virNetworkPortDeleteWrapper(virNetworkPortPtr port,
+ unsigned int flags,
+ virErrorPtr err)
+{
+#if LIBVIR_VERSION_NUMBER < 5005000
+ assert(0); // Caller should have checked version
+#else
+ int ret;
+ ret = virNetworkPortDelete(port, flags);
+ if (ret < 0) {
+ virCopyLastError(err);
+ }
+ return ret;
+#endif
+}
+
+
+int
+virNetworkPortFreeWrapper(virNetworkPortPtr port,
+ virErrorPtr err)
+{
+#if LIBVIR_VERSION_NUMBER < 5005000
+ assert(0); // Caller should have checked version
+#else
+ int ret;
+ ret = virNetworkPortFree(port);
+ if (ret < 0) {
+ virCopyLastError(err);
+ }
+ return ret;
+#endif
+}
+
+
+int
+virNetworkPortRefWrapper(virNetworkPortPtr port,
+ virErrorPtr err)
+{
+#if LIBVIR_VERSION_NUMBER < 5005000
+ assert(0); // Caller should have checked version
+#else
+ int ret;
+ ret = virNetworkPortRef(port);
+ if (ret < 0) {
+ virCopyLastError(err);
+ }
+ return ret;
+#endif
+}
+
+
+*/
+import "C"
diff --git a/network_port_wrapper.h b/network_port_wrapper.h
new file mode 100644
index 0000000..054d459
--- /dev/null
+++ b/network_port_wrapper.h
@@ -0,0 +1,79 @@
+/*
+ * This file is part of the libvirt-go project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * Copyright (C) 2019 Red Hat, Inc.
+ *
+ */
+
+#ifndef LIBVIRT_GO_NETWORK_PORT_WRAPPER_H__
+#define LIBVIRT_GO_NETWORK_PORT_WRAPPER_H__
+
+#include <libvirt/libvirt.h>
+#include <libvirt/virterror.h>
+#include "network_port_compat.h"
+
+
+virNetworkPtr
+virNetworkPortGetNetworkWrapper(virNetworkPortPtr port,
+ virErrorPtr err);
+
+char *
+virNetworkPortGetXMLDescWrapper(virNetworkPortPtr port,
+ unsigned int flags,
+ virErrorPtr err);
+
+int
+virNetworkPortGetUUIDWrapper(virNetworkPortPtr port,
+ unsigned char *uuid,
+ virErrorPtr err);
+int
+virNetworkPortGetUUIDStringWrapper(virNetworkPortPtr port,
+ char *buf,
+ virErrorPtr err);
+
+int
+virNetworkPortSetParametersWrapper(virNetworkPortPtr port,
+ virTypedParameterPtr params,
+ int nparams,
+ unsigned int flags,
+ virErrorPtr err);
+int
+virNetworkPortGetParametersWrapper(virNetworkPortPtr port,
+ virTypedParameterPtr *params,
+ int *nparams,
+ unsigned int flags,
+ virErrorPtr err);
+
+int
+virNetworkPortDeleteWrapper(virNetworkPortPtr port,
+ unsigned int flags,
+ virErrorPtr err);
+
+int
+virNetworkPortFreeWrapper(virNetworkPortPtr port,
+ virErrorPtr err);
+
+int
+virNetworkPortRefWrapper(virNetworkPortPtr port,
+ virErrorPtr err);
+
+
+#endif /* LIBVIRT_GO_NETWORK_PORT_WRAPPER_H__ */
diff --git a/network_wrapper.go b/network_wrapper.go
index 2fc443f..6105612 100644
--- a/network_wrapper.go
+++ b/network_wrapper.go
@@ -263,5 +263,78 @@ virNetworkUpdateWrapper(virNetworkPtr network,
}
+virNetworkPortPtr
+virNetworkPortLookupByUUIDWrapper(virNetworkPtr net,
+ const unsigned char *uuid,
+ virErrorPtr err)
+{
+#if LIBVIR_VERSION_NUMBER < 5005000
+ assert(0); // Caller should have checked version
+#else
+ virNetworkPortPtr ret;
+ ret = virNetworkPortLookupByUUID(net, uuid);
+ if (!ret) {
+ virCopyLastError(err);
+ }
+ return ret;
+#endif
+}
+
+virNetworkPortPtr
+virNetworkPortLookupByUUIDStringWrapper(virNetworkPtr net,
+ const char *uuidstr,
+ virErrorPtr err)
+{
+#if LIBVIR_VERSION_NUMBER < 5005000
+ assert(0); // Caller should have checked version
+#else
+ virNetworkPortPtr ret;
+ ret = virNetworkPortLookupByUUIDString(net, uuidstr);
+ if (!ret) {
+ virCopyLastError(err);
+ }
+ return ret;
+#endif
+}
+
+
+virNetworkPortPtr
+virNetworkPortCreateXMLWrapper(virNetworkPtr net,
+ const char *xmldesc,
+ unsigned int flags,
+ virErrorPtr err)
+{
+#if LIBVIR_VERSION_NUMBER < 5005000
+ assert(0); // Caller should have checked version
+#else
+ virNetworkPortPtr ret;
+ ret = virNetworkPortCreateXML(net, xmldesc, flags);
+ if (!ret) {
+ virCopyLastError(err);
+ }
+ return ret;
+#endif
+}
+
+
+int
+virNetworkListAllPortsWrapper(virNetworkPtr network,
+ virNetworkPortPtr **ports,
+ unsigned int flags,
+ virErrorPtr err)
+{
+#if LIBVIR_VERSION_NUMBER < 5005000
+ assert(0); // Caller should have checked version
+#else
+ int ret;
+ ret = virNetworkListAllPorts(network, ports, flags);
+ if (ret < 0) {
+ virCopyLastError(err);
+ }
+ return ret;
+#endif
+}
+
+
*/
import "C"
diff --git a/network_wrapper.h b/network_wrapper.h
index 405bf89..d76167b 100644
--- a/network_wrapper.h
+++ b/network_wrapper.h
@@ -30,6 +30,7 @@
#include <libvirt/libvirt.h>
#include <libvirt/virterror.h>
#include "network_compat.h"
+#include "network_port_compat.h"
int
virNetworkCreateWrapper(virNetworkPtr network,
@@ -115,5 +116,27 @@ virNetworkUpdateWrapper(virNetworkPtr network,
unsigned int flags,
virErrorPtr err);
+virNetworkPortPtr
+virNetworkPortLookupByUUIDWrapper(virNetworkPtr net,
+ const unsigned char *uuid,
+ virErrorPtr err);
+
+virNetworkPortPtr
+virNetworkPortLookupByUUIDStringWrapper(virNetworkPtr net,
+ const char *uuidstr,
+ virErrorPtr err);
+
+virNetworkPortPtr
+virNetworkPortCreateXMLWrapper(virNetworkPtr net,
+ const char *xmldesc,
+ unsigned int flags,
+ virErrorPtr err);
+
+int
+virNetworkListAllPortsWrapper(virNetworkPtr network,
+ virNetworkPortPtr **ports,
+ unsigned int flags,
+ virErrorPtr err);
+
#endif /* LIBVIRT_GO_NETWORK_WRAPPER_H__ */
--
2.21.0
5 years, 6 months
[libvirt] [PATCH 0/3] qemu: Introduce 'features' QMP query (blockdev-add saga)
by Peter Krempa
qemu introduced a new field in the QMP schema which allows to query
features for a schema entry. Add the support to libvirt for querying it.
Patch 3/3 is part of my blockdev series and I don't mind holding on to
it until I post patches which make use of it. It's posted here mostly
for demonstration purpose.
Peter Krempa (3):
tests: qemucaps: Introduce test data for qemu 4.1.0
qemu: qapi: Implement support for 'features'
qemu: caps: Add capability for dynamic 'auto-read-only' support for
files
src/qemu/qemu_capabilities.c | 2 +
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_qapi.c | 41 +
.../caps_4.1.0.x86_64.replies | 23482 ++++++++++++++++
.../caps_4.1.0.x86_64.xml | 1388 +
5 files changed, 24914 insertions(+)
create mode 100644 tests/qemucapabilitiesdata/caps_4.1.0.x86_64.replies
create mode 100644 tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml
--
2.21.0
5 years, 6 months
[libvirt] [PATCH] network: add virNetworkPortRef API
by Daniel P. Berrangé
Normal practice is to provide a Ref API for all objects, but this was
forgotten for the virNetworkPortPtr object.
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
include/libvirt/libvirt-network.h | 3 +++
src/libvirt-network.c | 32 +++++++++++++++++++++++++++++++
src/libvirt_public.syms | 1 +
3 files changed, 36 insertions(+)
diff --git a/include/libvirt/libvirt-network.h b/include/libvirt/libvirt-network.h
index 97eceef754..c9ff0a49ed 100644
--- a/include/libvirt/libvirt-network.h
+++ b/include/libvirt/libvirt-network.h
@@ -455,4 +455,7 @@ virNetworkListAllPorts(virNetworkPtr network,
int
virNetworkPortFree(virNetworkPortPtr port);
+int
+virNetworkPortRef(virNetworkPortPtr port);
+
#endif /* LIBVIRT_NETWORK_H */
diff --git a/src/libvirt-network.c b/src/libvirt-network.c
index 6ed32c8ba2..c182064c0f 100644
--- a/src/libvirt-network.c
+++ b/src/libvirt-network.c
@@ -1690,3 +1690,35 @@ virNetworkPortFree(virNetworkPortPtr port)
virObjectUnref(port);
return 0;
}
+
+
+/**
+ * virNetworkPortRef:
+ * @port: a network port object
+ *
+ * Increment the reference count on the network port. For each
+ * additional call to this method, there shall be a corresponding
+ * call to virNetworkPortFree to release the reference count, once
+ * the caller no longer needs the reference to this object.
+ *
+ * This method is typically useful for applications where multiple
+ * threads are using a network port, and it is required that the
+ * port remain resident until all threads have finished using
+ * it. ie, each new thread using a network port would increment
+ * the reference count.
+ *
+ * Returns 0 in case of success, -1 in case of failure.
+ */
+int
+virNetworkPortRef(virNetworkPortPtr port)
+{
+ VIR_DEBUG("port=%p refs=%d", port,
+ port ? port->parent.u.s.refs : 0);
+
+ virResetLastError();
+
+ virCheckNetworkPortReturn(port, -1);
+
+ virObjectRef(port);
+ return 0;
+}
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 46c32a081b..75f7fdfb0c 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -831,6 +831,7 @@ LIBVIRT_5.5.0 {
virNetworkPortGetUUIDString;
virNetworkPortDelete;
virNetworkPortFree;
+ virNetworkPortRef;
virNetworkPortSetParameters;
} LIBVIRT_5.2.0;
--
2.21.0
5 years, 6 months
[libvirt] [security-notice PATCH 0/9] various improvements to script for finding broken/fixed branches/tags
by Daniel P. Berrangé
This series provides for much greater automation when publishing
details of security flaws. It is now possible to just provide the broken
and fixed commit hash on the master branch. All the tag info and details
of branches are now filled in automatically.
Daniel P. Berrangé (9):
scripts: change data structures used to track branches & tags
scripts: report vulnerable branches which don't have any tags too
scripts: add ability to handle a fixed commit hash
scripts: change to update notice files inplace
scripts: allow for notices to have multiple commit hashes
scripts: optimize tag to branch mapping
scripts: add detection of cherry-picks in branches
scripts: fuzzy matching on subject to identify unannotated cherry
picks
notices: re-generate all branch/tag info
notices/2008/0001.xml | 6 -
notices/2009/0001.xml | 2 +
notices/2010/0001.xml | 3 -
notices/2010/0002.xml | 3 -
notices/2010/0004.xml | 2 +-
notices/2011/0001.xml | 10 +-
notices/2011/0002.xml | 4 +
notices/2012/0001.xml | 14 +-
notices/2012/0002.xml | 2 +-
notices/2012/0003.xml | 4 +
notices/2013/0001.xml | 8 +
notices/2013/0002.xml | 8 +
notices/2013/0003.xml | 21 ++
notices/2013/0005.xml | 2 +-
notices/2013/0006.xml | 1 +
notices/2013/0007.xml | 2 +-
notices/2013/0010.xml | 16 +-
notices/2013/0012.xml | 28 ++-
notices/2013/0015.xml | 2 +-
notices/2013/0016.xml | 22 ++-
notices/2013/0018.xml | 102 +++++-----
notices/2013/0020.xml | 68 ++++---
notices/2013/0021.xml | 2 +-
notices/2014/0001.xml | 8 +
notices/2014/0003.xml | 107 ++++++++--
notices/2014/0004.xml | 25 ++-
notices/2014/0005.xml | 21 +-
notices/2014/0006.xml | 22 ++-
notices/2014/0007.xml | 18 +-
notices/2014/0008.xml | 6 +-
notices/2014/0009.xml | 5 +-
notices/2014/0010.xml | 8 +-
notices/2015/0001.xml | 10 +-
notices/2015/0002.xml | 6 +-
notices/2015/0003.xml | 14 +-
notices/2015/0004.xml | 13 +-
notices/2016/0001.xml | 4 +-
notices/2016/0002.xml | 1 +
notices/2017/0001.xml | 4 +-
notices/2017/0002.xml | 6 +-
notices/2018/0001.xml | 159 ++++++++++++++-
notices/2018/0002.xml | 158 ++++++++++++++-
notices/2018/0003.xml | 161 ++++++++++++++-
notices/2018/0004.xml | 159 ++++++++++++++-
notices/2018/0005.xml | 162 ++++++++++++++-
notices/2019/0001.xml | 2 +-
notices/2019/0002.xml | 2 +-
scripts/report-vulnerable-tags.pl | 319 ++++++++++++++++++++++++++----
48 files changed, 1507 insertions(+), 225 deletions(-)
--
2.21.0
5 years, 6 months
[libvirt] [PATCH] conf: remove unused class_id variable
by Daniel P. Berrangé
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
Pushed as a build fix
src/conf/virnetworkportdef.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/conf/virnetworkportdef.c b/src/conf/virnetworkportdef.c
index 5dfa3a3583..29ecf5b178 100644
--- a/src/conf/virnetworkportdef.c
+++ b/src/conf/virnetworkportdef.c
@@ -88,7 +88,6 @@ virNetworkPortDefParseXML(xmlXPathContextPtr ctxt)
VIR_AUTOFREE(char *) plugtype = NULL;
VIR_AUTOFREE(char *) managed = NULL;
VIR_AUTOFREE(char *) driver = NULL;
- VIR_AUTOFREE(char *) class_id = NULL;
if (VIR_ALLOC(def) < 0)
return NULL;
--
2.21.0
5 years, 6 months
[libvirt] [PATCH v2 0/4] Misc fixes to network port code
by Daniel P. Berrangé
Fixes for bugs spotted by coverity
Daniel P. Berrangé (4):
conf: fix leak when parsing network port XML
conf: fix leak of directory handle when loading network ports
conf: fix NULL deref when exporting ports
conf: add error checking of UUID generation
src/conf/domain_conf.c | 12 ++++++++++--
src/conf/virnetworkobj.c | 9 ++++++---
src/conf/virnetworkportdef.c | 26 +++++++++-----------------
3 files changed, 25 insertions(+), 22 deletions(-)
--
2.21.0
5 years, 6 months
[libvirt] [go-xml PATCH] Add support for network filter binding XML schema
by Daniel P. Berrangé
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
nwfilter_binding.go | 73 +++++++++++++++++++++++++++++++++++++++++++++
xml_test.go | 3 ++
2 files changed, 76 insertions(+)
create mode 100644 nwfilter_binding.go
diff --git a/nwfilter_binding.go b/nwfilter_binding.go
new file mode 100644
index 0000000..918ab71
--- /dev/null
+++ b/nwfilter_binding.go
@@ -0,0 +1,73 @@
+/*
+ * This file is part of the libvirt-go-xml project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * Copyright (C) 2017 Lian Duan <blazeblue(a)gmail.com>
+ *
+ */
+
+package libvirtxml
+
+import (
+ "encoding/xml"
+)
+
+type NWFilterBinding struct {
+ XMLName xml.Name `xml:"filterbinding"`
+ Owner *NWFilterBindingOwner `xml:"owner"`
+ PortDev *NWFilterBindingPortDev `xml:"portdev"`
+ MAC *NWFilterBindingMAC `xml:"mac"`
+ FilterRef *NWFilterBindingFilterRef `xml:"filterref"`
+}
+
+type NWFilterBindingOwner struct {
+ UUID string `xml:"uuid,omitempty"`
+ Name string `xml:"name,omitempty"`
+}
+
+type NWFilterBindingPortDev struct {
+ Name string `xml:"name,attr"`
+}
+
+type NWFilterBindingMAC struct {
+ Address string `xml:"address,attr"`
+}
+
+type NWFilterBindingFilterRef struct {
+ Filter string `xml:"filter,attr"`
+ Parameters []NWFilterBindingFilterParam `xml:"parameter"`
+}
+
+type NWFilterBindingFilterParam struct {
+ Name string `xml:"name,attr"`
+ Value string `xml:"value,attr"`
+}
+
+func (s *NWFilterBinding) Unmarshal(doc string) error {
+ return xml.Unmarshal([]byte(doc), s)
+}
+
+func (s *NWFilterBinding) Marshal() (string, error) {
+ doc, err := xml.MarshalIndent(s, "", " ")
+ if err != nil {
+ return "", err
+ }
+ return string(doc), nil
+}
diff --git a/xml_test.go b/xml_test.go
index 320c248..d1da879 100644
--- a/xml_test.go
+++ b/xml_test.go
@@ -83,6 +83,7 @@ var xmldirs = []string{
"testdata/libvirt/tests/storagevolxml2xmlin",
"testdata/libvirt/tests/storagevolxml2xmlout",
"testdata/libvirt/tests/vircaps2xmldata",
+ "testdata/libvirt/tests/virnwfilterbindingxml2xmldata",
"testdata/libvirt/tests/virstorageutildata",
"testdata/libvirt/tests/vmx2xmldata",
"testdata/libvirt/tests/xlconfigdata",
@@ -325,6 +326,8 @@ func testRoundTrip(t *testing.T, xml string, filename string) {
} else {
doc = &CapsHostCPU{}
}
+ } else if strings.HasPrefix(xml, "<filterbinding") {
+ doc = &NWFilterBinding{}
} else if strings.HasPrefix(xml, "<filter") {
doc = &NWFilter{}
} else if strings.HasPrefix(xml, "<interface") {
--
2.21.0
5 years, 6 months