From: "Daniel P. Berrange" <berrange(a)redhat.com>
The src/util/network.c file is a dumping ground for many different
APIs. Split it up into 5 pieces, along functional lines
- src/util/virnetdevbandwidth.c: virNetDevBandwidth type & helper APIs
- src/util/virnetdevvportprofile.c: virNetDevVPortProfile type & helper APIs
- src/util/virsocketaddr.c: virSocketAddr and APIs
- src/conf/netdev_bandwidth_conf.c: XML parsing / formatting
for virNetDevBandwidth
- src/conf/netdev_vport_profile_conf.c: XML parsing / formatting
for virNetDevVPortProfile
* src/util/network.c, src/util/network.h: Split into 5 pieces
* src/conf/netdev_bandwidth_conf.c, src/conf/netdev_bandwidth_conf.h,
src/conf/netdev_vport_profile_conf.c, src/conf/netdev_vport_profile_conf.h,
src/util/virnetdevbandwidth.c, src/util/virnetdevbandwidth.h,
src/util/virnetdevvportprofile.c, src/util/virnetdevvportprofile.h,
src/util/virsocketaddr.c, src/util/virsocketaddr.h: New pieces
* daemon/libvirtd.h, daemon/remote.c, src/conf/domain_conf.c,
src/conf/domain_conf.h, src/conf/network_conf.c,
src/conf/network_conf.h, src/conf/nwfilter_conf.h,
src/esx/esx_util.h, src/network/bridge_driver.c,
src/qemu/qemu_conf.c, src/rpc/virnetsocket.c,
src/rpc/virnetsocket.h, src/util/dnsmasq.h, src/util/interface.h,
src/util/iptables.h, src/util/macvtap.c, src/util/macvtap.h,
src/util/virnetdev.h, src/util/virnetdevtap.c,
tools/virsh.c: Update include files
---
daemon/libvirtd.h | 1 -
daemon/remote.c | 1 -
po/POTFILES.in | 4 +-
src/Makefile.am | 12 +-
src/conf/domain_conf.c | 3 +-
src/conf/domain_conf.h | 4 +-
src/conf/netdev_bandwidth_conf.c | 230 ++++++
src/conf/netdev_bandwidth_conf.h | 37 +
src/conf/netdev_vport_profile_conf.c | 236 ++++++
src/conf/netdev_vport_profile_conf.h | 39 +
src/conf/network_conf.c | 3 +-
src/conf/network_conf.h | 4 +-
src/conf/nwfilter_conf.h | 2 +-
src/esx/esx_util.h | 2 +-
src/network/bridge_driver.c | 1 -
src/qemu/qemu_conf.c | 1 -
src/rpc/virnetsocket.c | 1 +
src/rpc/virnetsocket.h | 2 +-
src/util/dnsmasq.h | 2 +-
src/util/interface.h | 2 +-
src/util/iptables.h | 2 +-
src/util/macvtap.c | 1 -
src/util/macvtap.h | 8 +-
src/util/network.c | 1349 ----------------------------------
src/util/network.h | 173 -----
src/util/virnetdev.h | 2 +-
src/util/virnetdevbandwidth.c | 265 +++++++
src/util/virnetdevbandwidth.h | 53 ++
src/util/virnetdevtap.c | 1 +
src/util/virnetdevvportprofile.c | 62 ++
src/util/virnetdevvportprofile.h | 64 ++
src/util/virsocketaddr.c | 687 +++++++++++++++++
src/util/virsocketaddr.h | 103 +++
tools/virsh.c | 2 +-
34 files changed, 1813 insertions(+), 1546 deletions(-)
create mode 100644 src/conf/netdev_bandwidth_conf.c
create mode 100644 src/conf/netdev_bandwidth_conf.h
create mode 100644 src/conf/netdev_vport_profile_conf.c
create mode 100644 src/conf/netdev_vport_profile_conf.h
delete mode 100644 src/util/network.c
delete mode 100644 src/util/network.h
create mode 100644 src/util/virnetdevbandwidth.c
create mode 100644 src/util/virnetdevbandwidth.h
create mode 100644 src/util/virnetdevvportprofile.c
create mode 100644 src/util/virnetdevvportprofile.h
create mode 100644 src/util/virsocketaddr.c
create mode 100644 src/util/virsocketaddr.h
diff --git a/daemon/libvirtd.h b/daemon/libvirtd.h
index ecb7374..ce787a4 100644
--- a/daemon/libvirtd.h
+++ b/daemon/libvirtd.h
@@ -33,7 +33,6 @@
# include "qemu_protocol.h"
# include "logging.h"
# include "threads.h"
-# include "network.h"
# if HAVE_SASL
# include "virnetsaslcontext.h"
# endif
diff --git a/daemon/remote.c b/daemon/remote.c
index bd0c3e3..b028352 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -38,7 +38,6 @@
#include "util.h"
#include "stream.h"
#include "uuid.h"
-#include "network.h"
#include "libvirt/libvirt-qemu.h"
#include "command.h"
#include "intprops.h"
diff --git a/po/POTFILES.in b/po/POTFILES.in
index a3685e8..1665d2d 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -8,6 +8,8 @@ src/conf/cpu_conf.c
src/conf/domain_conf.c
src/conf/domain_event.c
src/conf/interface_conf.c
+src/conf/netdev_bandwidth_conf.c
+src/conf/netdev_vport_profile_conf.c
src/conf/network_conf.c
src/conf/node_device_conf.c
src/conf/nwfilter_conf.c
@@ -116,7 +118,6 @@ src/util/iptables.c
src/util/json.c
src/util/macvtap.c
src/util/netlink.c
-src/util/network.c
src/util/pci.c
src/util/processinfo.c
src/util/sexpr.c
@@ -130,6 +131,7 @@ src/util/virnetdev.c
src/util/virnetdevbridge.c
src/util/virnetdevtap.c
src/util/virpidfile.c
+src/util/virsocketaddr.c
src/util/virterror.c
src/util/xml.c
src/vbox/vbox_MSCOMGlue.c
diff --git a/src/Makefile.am b/src/Makefile.am
index f742f2a..2faf659 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -71,7 +71,6 @@ UTIL_SOURCES = \
util/pci.c util/pci.h \
util/processinfo.c util/processinfo.h \
util/hostusb.c util/hostusb.h \
- util/network.c util/network.h \
util/interface.c util/interface.h \
util/qparams.c util/qparams.h \
util/sexpr.c util/sexpr.h \
@@ -92,8 +91,11 @@ UTIL_SOURCES = \
util/virkeycode.c util/virkeycode.h \
util/virkeymaps.h \
util/virnetdev.h util/virnetdev.c \
+ util/virnetdevbandwidth.h util/virnetdevbandwidth.c \
util/virnetdevbridge.h util/virnetdevbridge.c \
- util/virnetdevtap.h util/virnetdevtap.c
+ util/virnetdevtap.h util/virnetdevtap.c \
+ util/virnetdevvportprofile.h util/virnetdevvportprofile.c \
+ util/virsocketaddr.h util/virsocketaddr.c
EXTRA_DIST += $(srcdir)/util/virkeymaps.h $(srcdir)/util/keymaps.csv \
$(srcdir)/util/virkeycode-mapgen.py
@@ -124,6 +126,10 @@ LOCK_DRIVER_SANLOCK_SOURCES = \
locking/lock_driver_sanlock.c
+NETDEV_CONF_SOURCES = \
+ conf/netdev_bandwidth_conf.h conf/netdev_bandwidth_conf.c \
+ conf/netdev_vport_profile_conf.h conf/netdev_vport_profile_conf.c
+
# XML configuration format handling sources
# Domain driver generic impl APIs
DOMAIN_CONF_SOURCES = \
@@ -171,6 +177,7 @@ CPU_CONF_SOURCES = \
conf/cpu_conf.c conf/cpu_conf.h
CONF_SOURCES = \
+ $(NETDEV_CONF_SOURCES) \
$(DOMAIN_CONF_SOURCES) \
$(DOMAIN_EVENT_SOURCES) \
$(NETWORK_CONF_SOURCES) \
@@ -1477,6 +1484,7 @@ libvirt_lxc_SOURCES = \
$(UTIL_SOURCES) \
$(NODE_INFO_SOURCES) \
$(ENCRYPTION_CONF_SOURCES) \
+ $(NETDEV_CONF_SOURCES) \
$(DOMAIN_CONF_SOURCES) \
$(SECRET_CONF_SOURCES) \
$(CPU_CONF_SOURCES) \
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index b1e47a3..b3c3339 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -42,7 +42,6 @@
#include "buf.h"
#include "c-ctype.h"
#include "logging.h"
-#include "network.h"
#include "nwfilter_conf.h"
#include "ignore-value.h"
#include "storage_file.h"
@@ -50,6 +49,8 @@
#include "bitmap.h"
#include "count-one-bits.h"
#include "secret_conf.h"
+#include "netdev_vport_profile_conf.h"
+#include "netdev_bandwidth_conf.h"
#define VIR_FROM_THIS VIR_FROM_DOMAIN
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 255d8fd..c360674 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -35,11 +35,13 @@
# include "util.h"
# include "threads.h"
# include "hash.h"
-# include "network.h"
+# include "virsocketaddr.h"
# include "nwfilter_params.h"
# include "nwfilter_conf.h"
# include "macvtap.h"
# include "sysinfo.h"
+# include "virnetdevvportprofile.h"
+# include "virnetdevbandwidth.h"
/* Different types of hypervisor */
/* NB: Keep in sync with virDomainVirtTypeToString impl */
diff --git a/src/conf/netdev_bandwidth_conf.c b/src/conf/netdev_bandwidth_conf.c
new file mode 100644
index 0000000..24cd13d
--- /dev/null
+++ b/src/conf/netdev_bandwidth_conf.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2009-2011 Red Hat, 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors:
+ * Michal Privoznik <mprivozn(a)redhat.com>
+ * Daniel P. Berrange <berrange(a)redhat.com>
+ */
+
+#include <config.h>
+
+#include "netdev_bandwidth_conf.h"
+#include "virterror_internal.h"
+#include "util.h"
+#include "memory.h"
+
+#define VIR_FROM_THIS VIR_FROM_NONE
+#define virNetDevError(code, ...) \
+ virReportErrorHelper(VIR_FROM_THIS, code, __FILE__, \
+ __FUNCTION__, __LINE__, __VA_ARGS__)
+
+
+static int
+virNetDevBandwidthParseRate(xmlNodePtr node, virNetDevBandwidthRatePtr rate)
+{
+ int ret = -1;
+ char *average = NULL;
+ char *peak = NULL;
+ char *burst = NULL;
+
+ if (!node || !rate) {
+ virNetDevError(VIR_ERR_INVALID_ARG, "%s",
+ _("invalid argument supplied"));
+ return -1;
+ }
+
+ average = virXMLPropString(node, "average");
+ peak = virXMLPropString(node, "peak");
+ burst = virXMLPropString(node, "burst");
+
+ if (average) {
+ if (virStrToLong_ull(average, NULL, 10, &rate->average) < 0) {
+ virNetDevError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("could not convert %s"),
+ average);
+ goto cleanup;
+ }
+ } else {
+ virNetDevError(VIR_ERR_XML_DETAIL, "%s",
+ _("Missing mandatory average attribute"));
+ goto cleanup;
+ }
+
+ if (peak && virStrToLong_ull(peak, NULL, 10, &rate->peak) < 0) {
+ virNetDevError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("could not convert %s"),
+ peak);
+ goto cleanup;
+ }
+
+ if (burst && virStrToLong_ull(burst, NULL, 10, &rate->burst) < 0)
{
+ virNetDevError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("could not convert %s"),
+ burst);
+ goto cleanup;
+ }
+
+ ret = 0;
+
+cleanup:
+ VIR_FREE(average);
+ VIR_FREE(peak);
+ VIR_FREE(burst);
+
+ return ret;
+}
+
+/**
+ * virNetDevBandwidthParse:
+ * @node: XML node
+ *
+ * Parse bandwidth XML and return pointer to structure
+ *
+ * Returns !NULL on success, NULL on error.
+ */
+virNetDevBandwidthPtr
+virNetDevBandwidthParse(xmlNodePtr node)
+{
+ virNetDevBandwidthPtr def = NULL;
+ xmlNodePtr cur = node->children;
+ xmlNodePtr in = NULL, out = NULL;
+
+ if (VIR_ALLOC(def) < 0) {
+ virReportOOMError();
+ return NULL;
+ }
+
+ if (!node || !xmlStrEqual(node->name, BAD_CAST "bandwidth")) {
+ virNetDevError(VIR_ERR_INVALID_ARG, "%s",
+ _("invalid argument supplied"));
+ goto error;
+ }
+
+ while (cur) {
+ if (cur->type == XML_ELEMENT_NODE) {
+ if (xmlStrEqual(cur->name, BAD_CAST "inbound")) {
+ if (in) {
+ virNetDevError(VIR_ERR_XML_DETAIL, "%s",
+ _("Only one child <inbound> "
+ "element allowed"));
+ goto error;
+ }
+ in = cur;
+ } else if (xmlStrEqual(cur->name, BAD_CAST "outbound")) {
+ if (out) {
+ virNetDevError(VIR_ERR_XML_DETAIL, "%s",
+ _("Only one child <outbound> "
+ "element allowed"));
+ goto error;
+ }
+ out = cur;
+ }
+ /* Silently ignore unknown elements */
+ }
+ cur = cur->next;
+ }
+
+ if (in) {
+ if (VIR_ALLOC(def->in) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+
+ if (virNetDevBandwidthParseRate(in, def->in) < 0) {
+ /* helper reported error for us */
+ goto error;
+ }
+ }
+
+ if (out) {
+ if (VIR_ALLOC(def->out) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+
+ if (virNetDevBandwidthParseRate(out, def->out) < 0) {
+ /* helper reported error for us */
+ goto error;
+ }
+ }
+
+ return def;
+
+error:
+ virNetDevBandwidthFree(def);
+ return NULL;
+}
+
+static int
+virNetDevBandwidthRateFormat(virNetDevBandwidthRatePtr def,
+ virBufferPtr buf,
+ const char *elem_name)
+{
+ if (!buf || !elem_name)
+ return -1;
+ if (!def)
+ return 0;
+
+ if (def->average) {
+ virBufferAsprintf(buf, " <%s average='%llu'", elem_name,
+ def->average);
+
+ if (def->peak)
+ virBufferAsprintf(buf, " peak='%llu'", def->peak);
+
+ if (def->burst)
+ virBufferAsprintf(buf, " burst='%llu'", def->burst);
+ virBufferAddLit(buf, "/>\n");
+ }
+
+ return 0;
+}
+
+/**
+ * virNetDevBandwidthDefFormat:
+ * @def: Data source
+ * @buf: Buffer to print to
+ *
+ * Formats bandwidth and prepend each line with @indent.
+ * @buf may use auto-indentation.
+ *
+ * Returns 0 on success, else -1.
+ */
+int
+virNetDevBandwidthFormat(virNetDevBandwidthPtr def, virBufferPtr buf)
+{
+ int ret = -1;
+
+ if (!buf)
+ goto cleanup;
+
+ if (!def) {
+ ret = 0;
+ goto cleanup;
+ }
+
+ virBufferAddLit(buf, "<bandwidth>\n");
+ if (virNetDevBandwidthRateFormat(def->in, buf, "inbound") < 0 ||
+ virNetDevBandwidthRateFormat(def->out, buf, "outbound") < 0)
+ goto cleanup;
+ virBufferAddLit(buf, "</bandwidth>\n");
+
+ ret = 0;
+
+cleanup:
+ return ret;
+}
diff --git a/src/conf/netdev_bandwidth_conf.h b/src/conf/netdev_bandwidth_conf.h
new file mode 100644
index 0000000..4bb7def
--- /dev/null
+++ b/src/conf/netdev_bandwidth_conf.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2009-2011 Red Hat, 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors:
+ * Michal Privoznik <mprivozn(a)redhat.com>
+ * Daniel P. Berrange <berrange(a)redhat.com>
+ */
+
+#ifndef __VIR_NETDEV_BANDWIDTH_CONF_H__
+# define __VIR_NETDEV_BANDWIDTH_CONF_H__
+
+# include "internal.h"
+# include "virnetdevbandwidth.h"
+# include "buf.h"
+# include "xml.h"
+
+virNetDevBandwidthPtr virNetDevBandwidthParse(xmlNodePtr node)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
+int virNetDevBandwidthFormat(virNetDevBandwidthPtr def,
+ virBufferPtr buf)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+
+#endif /* __VIR_NETDEV_BANDWIDTH_CONF_H__ */
diff --git a/src/conf/netdev_vport_profile_conf.c b/src/conf/netdev_vport_profile_conf.c
new file mode 100644
index 0000000..63c6668
--- /dev/null
+++ b/src/conf/netdev_vport_profile_conf.c
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2009-2011 Red Hat, 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors:
+ * Laine Stump <laine(a)laine.org>
+ * Daniel P. Berrange <berrange(a)redhat.com>
+ */
+
+#include <config.h>
+
+#include "netdev_vport_profile_conf.h"
+#include "virterror_internal.h"
+#include "memory.h"
+
+#define VIR_FROM_THIS VIR_FROM_NONE
+#define virNetDevError(code, ...) \
+ virReportErrorHelper(VIR_FROM_THIS, code, __FILE__, \
+ __FUNCTION__, __LINE__, __VA_ARGS__)
+
+
+VIR_ENUM_IMPL(virNetDevVPort, VIR_NETDEV_VPORT_PROFILE_LAST,
+ "none",
+ "802.1Qbg",
+ "802.1Qbh")
+
+
+virNetDevVPortProfilePtr
+virNetDevVPortProfileParse(xmlNodePtr node)
+{
+ char *virtPortType;
+ char *virtPortManagerID = NULL;
+ char *virtPortTypeID = NULL;
+ char *virtPortTypeIDVersion = NULL;
+ char *virtPortInstanceID = NULL;
+ char *virtPortProfileID = NULL;
+ virNetDevVPortProfilePtr virtPort = NULL;
+ xmlNodePtr cur = node->children;
+
+ if (VIR_ALLOC(virtPort) < 0) {
+ virReportOOMError();
+ return NULL;
+ }
+
+ virtPortType = virXMLPropString(node, "type");
+ if (!virtPortType) {
+ virNetDevError(VIR_ERR_XML_ERROR, "%s",
+ _("missing virtualportprofile type"));
+ goto error;
+ }
+
+ if ((virtPort->virtPortType = virNetDevVPortTypeFromString(virtPortType)) <= 0)
{
+ virNetDevError(VIR_ERR_XML_ERROR,
+ _("unknown virtualportprofile type %s"), virtPortType);
+ goto error;
+ }
+
+ while (cur != NULL) {
+ if (xmlStrEqual(cur->name, BAD_CAST "parameters")) {
+
+ virtPortManagerID = virXMLPropString(cur, "managerid");
+ virtPortTypeID = virXMLPropString(cur, "typeid");
+ virtPortTypeIDVersion = virXMLPropString(cur, "typeidversion");
+ virtPortInstanceID = virXMLPropString(cur, "instanceid");
+ virtPortProfileID = virXMLPropString(cur, "profileid");
+
+ break;
+ }
+
+ cur = cur->next;
+ }
+
+ switch (virtPort->virtPortType) {
+ case VIR_NETDEV_VPORT_PROFILE_8021QBG:
+ if (virtPortManagerID != NULL && virtPortTypeID != NULL
&&
+ virtPortTypeIDVersion != NULL) {
+ unsigned int val;
+
+ if (virStrToLong_ui(virtPortManagerID, NULL, 0, &val)) {
+ virNetDevError(VIR_ERR_XML_ERROR, "%s",
+ _("cannot parse value of managerid
parameter"));
+ goto error;
+ }
+
+ if (val > 0xff) {
+ virNetDevError(VIR_ERR_XML_ERROR, "%s",
+ _("value of managerid out of range"));
+ goto error;
+ }
+
+ virtPort->u.virtPort8021Qbg.managerID = (uint8_t)val;
+
+ if (virStrToLong_ui(virtPortTypeID, NULL, 0, &val)) {
+ virNetDevError(VIR_ERR_XML_ERROR, "%s",
+ _("cannot parse value of typeid
parameter"));
+ goto error;
+ }
+
+ if (val > 0xffffff) {
+ virNetDevError(VIR_ERR_XML_ERROR, "%s",
+ _("value for typeid out of range"));
+ goto error;
+ }
+
+ virtPort->u.virtPort8021Qbg.typeID = (uint32_t)val;
+
+ if (virStrToLong_ui(virtPortTypeIDVersion, NULL, 0, &val)) {
+ virNetDevError(VIR_ERR_XML_ERROR, "%s",
+ _("cannot parse value of typeidversion
parameter"));
+ goto error;
+ }
+
+ if (val > 0xff) {
+ virNetDevError(VIR_ERR_XML_ERROR, "%s",
+ _("value of typeidversion out of
range"));
+ goto error;
+ }
+
+ virtPort->u.virtPort8021Qbg.typeIDVersion = (uint8_t)val;
+
+ if (virtPortInstanceID != NULL) {
+ if (virUUIDParse(virtPortInstanceID,
+ virtPort->u.virtPort8021Qbg.instanceID)) {
+ virNetDevError(VIR_ERR_XML_ERROR, "%s",
+ _("cannot parse instanceid parameter as a
uuid"));
+ goto error;
+ }
+ } else {
+ if (virUUIDGenerate(virtPort->u.virtPort8021Qbg.instanceID)) {
+ virNetDevError(VIR_ERR_XML_ERROR, "%s",
+ _("cannot generate a random uuid for
instanceid"));
+ goto error;
+ }
+ }
+
+ virtPort->virtPortType = VIR_NETDEV_VPORT_PROFILE_8021QBG;
+
+ } else {
+ virNetDevError(VIR_ERR_XML_ERROR, "%s",
+ _("a parameter is missing for 802.1Qbg
description"));
+ goto error;
+ }
+ break;
+
+ case VIR_NETDEV_VPORT_PROFILE_8021QBH:
+ if (virtPortProfileID != NULL) {
+ if (virStrcpyStatic(virtPort->u.virtPort8021Qbh.profileID,
+ virtPortProfileID) != NULL) {
+ virtPort->virtPortType = VIR_NETDEV_VPORT_PROFILE_8021QBH;
+ } else {
+ virNetDevError(VIR_ERR_XML_ERROR, "%s",
+ _("profileid parameter too long"));
+ goto error;
+ }
+ } else {
+ virNetDevError(VIR_ERR_XML_ERROR, "%s",
+ _("profileid parameter is missing for 802.1Qbh
descripion"));
+ goto error;
+ }
+ break;
+
+ default:
+ virNetDevError(VIR_ERR_XML_ERROR,
+ _("unexpected virtualport type %d"),
virtPort->virtPortType);
+ goto error;
+ }
+
+cleanup:
+ VIR_FREE(virtPortManagerID);
+ VIR_FREE(virtPortTypeID);
+ VIR_FREE(virtPortTypeIDVersion);
+ VIR_FREE(virtPortInstanceID);
+ VIR_FREE(virtPortProfileID);
+ VIR_FREE(virtPortType);
+
+ return virtPort;
+
+error:
+ VIR_FREE(virtPort);
+ goto cleanup;
+}
+
+
+int
+virNetDevVPortProfileFormat(virNetDevVPortProfilePtr virtPort,
+ virBufferPtr buf)
+{
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+
+ if (!virtPort || virtPort->virtPortType == VIR_NETDEV_VPORT_PROFILE_NONE)
+ return 0;
+
+ virBufferAsprintf(buf, "<virtualport type='%s'>\n",
+ virNetDevVPortTypeToString(virtPort->virtPortType));
+
+ switch (virtPort->virtPortType) {
+ case VIR_NETDEV_VPORT_PROFILE_8021QBG:
+ virUUIDFormat(virtPort->u.virtPort8021Qbg.instanceID,
+ uuidstr);
+ virBufferAsprintf(buf,
+ " <parameters managerid='%d'
typeid='%d' "
+ "typeidversion='%d'
instanceid='%s'/>\n",
+ virtPort->u.virtPort8021Qbg.managerID,
+ virtPort->u.virtPort8021Qbg.typeID,
+ virtPort->u.virtPort8021Qbg.typeIDVersion,
+ uuidstr);
+ break;
+
+ case VIR_NETDEV_VPORT_PROFILE_8021QBH:
+ virBufferAsprintf(buf,
+ " <parameters profileid='%s'/>\n",
+ virtPort->u.virtPort8021Qbh.profileID);
+ break;
+
+ default:
+ virNetDevError(VIR_ERR_XML_ERROR,
+ _("unexpected virtualport type %d"),
virtPort->virtPortType);
+ return -1;
+ }
+
+ virBufferAddLit(buf, "</virtualport>\n");
+ return 0;
+}
diff --git a/src/conf/netdev_vport_profile_conf.h b/src/conf/netdev_vport_profile_conf.h
new file mode 100644
index 0000000..3ab6975
--- /dev/null
+++ b/src/conf/netdev_vport_profile_conf.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2009-2011 Red Hat, 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors:
+ * Laine Stump <laine(a)laine.org>
+ * Daniel P. Berrange <berrange(a)redhat.com>
+ */
+
+#ifndef __VIR_NETDEV_VPORT_PROFILE_CONF_H__
+# define __VIR_NETDEV_VPORT_PROFILE_CONF_H__
+
+# include "internal.h"
+# include "virnetdevvportprofile.h"
+# include "buf.h"
+# include "xml.h"
+
+virNetDevVPortProfilePtr
+virNetDevVPortProfileParse(xmlNodePtr node);
+
+int
+virNetDevVPortProfileFormat(virNetDevVPortProfilePtr virtPort,
+ virBufferPtr buf);
+
+
+#endif /* __VIR_NETDEV_VPORT_PROFILE_CONF_H__ */
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 5e38bee..10afcde 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -34,7 +34,8 @@
#include "virterror_internal.h"
#include "datatypes.h"
#include "network_conf.h"
-#include "network.h"
+#include "netdev_vport_profile_conf.h"
+#include "netdev_bandwidth_conf.h"
#include "memory.h"
#include "xml.h"
#include "uuid.h"
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index 57ad637..1be20f8 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -30,7 +30,9 @@
# include "internal.h"
# include "threads.h"
-# include "network.h"
+# include "virsocketaddr.h"
+# include "virnetdevbandwidth.h"
+# include "virnetdevvportprofile.h"
# include "util.h"
enum virNetworkForwardType {
diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h
index c96851a..f48c7cd 100644
--- a/src/conf/nwfilter_conf.h
+++ b/src/conf/nwfilter_conf.h
@@ -35,7 +35,7 @@
# include "hash.h"
# include "xml.h"
# include "buf.h"
-# include "network.h"
+# include "virsocketaddr.h"
/* XXX
* The config parser/structs should not be using platform specific
diff --git a/src/esx/esx_util.h b/src/esx/esx_util.h
index 8d172e1..2bee510 100644
--- a/src/esx/esx_util.h
+++ b/src/esx/esx_util.h
@@ -23,7 +23,7 @@
# define __ESX_UTIL_H__
# include <libxml/uri.h>
-
+# include <netdb.h>
# include "internal.h"
typedef struct _esxUtil_ParsedUri esxUtil_ParsedUri;
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index b297f47..e68712f 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -59,7 +59,6 @@
#include "interface.h"
#include "logging.h"
#include "dnsmasq.h"
-#include "util/network.h"
#include "configmake.h"
#include "ignore-value.h"
#include "virnetdev.h"
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index d1bf075..4c20d17 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -50,7 +50,6 @@
#include "xml.h"
#include "nodeinfo.h"
#include "logging.h"
-#include "network.h"
#include "macvtap.h"
#include "cpu/cpu.h"
#include "domain_nwfilter.h"
diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c
index 3c9f327..8ef4887 100644
--- a/src/rpc/virnetsocket.c
+++ b/src/rpc/virnetsocket.c
@@ -29,6 +29,7 @@
#include <sys/wait.h>
#include <signal.h>
#include <fcntl.h>
+#include <netdb.h>
#ifdef HAVE_NETINET_TCP_H
# include <netinet/tcp.h>
diff --git a/src/rpc/virnetsocket.h b/src/rpc/virnetsocket.h
index 13cbb14..b795ab9 100644
--- a/src/rpc/virnetsocket.h
+++ b/src/rpc/virnetsocket.h
@@ -24,7 +24,7 @@
#ifndef __VIR_NET_SOCKET_H__
# define __VIR_NET_SOCKET_H__
-# include "network.h"
+# include "virsocketaddr.h"
# include "command.h"
# include "virnettlscontext.h"
# ifdef HAVE_SASL
diff --git a/src/util/dnsmasq.h b/src/util/dnsmasq.h
index d16a54f..2bec726 100644
--- a/src/util/dnsmasq.h
+++ b/src/util/dnsmasq.h
@@ -22,7 +22,7 @@
#ifndef __DNSMASQ_H__
# define __DNSMASQ_H__
-# include "network.h"
+# include "virsocketaddr.h"
typedef struct
{
diff --git a/src/util/interface.h b/src/util/interface.h
index 7be1444..3603c68 100644
--- a/src/util/interface.h
+++ b/src/util/interface.h
@@ -25,7 +25,7 @@ struct nlattr;
# endif
# include "datatypes.h"
-# include "network.h"
+# include "virsocketaddr.h"
# define NET_SYSFS "/sys/class/net/"
diff --git a/src/util/iptables.h b/src/util/iptables.h
index 572d612..429f29c 100644
--- a/src/util/iptables.h
+++ b/src/util/iptables.h
@@ -22,7 +22,7 @@
#ifndef __QEMUD_IPTABLES_H__
# define __QEMUD_IPTABLES_H__
-# include "network.h"
+# include "virsocketaddr.h"
typedef struct _iptablesContext iptablesContext;
diff --git a/src/util/macvtap.c b/src/util/macvtap.c
index 71243b8..c4629ed 100644
--- a/src/util/macvtap.c
+++ b/src/util/macvtap.c
@@ -50,7 +50,6 @@
#include "util.h"
#include "macvtap.h"
-#include "network.h"
VIR_ENUM_IMPL(virMacvtapMode, VIR_MACVTAP_MODE_LAST,
"vepa",
diff --git a/src/util/macvtap.h b/src/util/macvtap.h
index d685ab9..a6b00fe 100644
--- a/src/util/macvtap.h
+++ b/src/util/macvtap.h
@@ -23,7 +23,10 @@
#ifndef __UTIL_MACVTAP_H__
# define __UTIL_MACVTAP_H__
-# include <config.h>
+# include "internal.h"
+# include "virsocketaddr.h"
+# include "virnetdevbandwidth.h"
+# include "virnetdevvportprofile.h"
/* the mode type for macvtap devices */
enum virMacvtapMode {
@@ -50,9 +53,6 @@ enum virVMOperationType {
# if WITH_MACVTAP
-# include "internal.h"
-# include "network.h"
-
int openMacvtapTap(const char *ifname,
const unsigned char *macaddress,
const char *linkdev,
diff --git a/src/util/network.c b/src/util/network.c
deleted file mode 100644
index c467121..0000000
--- a/src/util/network.c
+++ /dev/null
@@ -1,1349 +0,0 @@
-/*
- * network.c: network helper APIs for libvirt
- *
- * Copyright (C) 2009-2011 Red Hat, Inc.
- *
- * See COPYING.LIB for the License of this software
- *
- * Daniel Veillard <veillard(a)redhat.com>
- */
-
-#include <config.h>
-#include <arpa/inet.h>
-
-#include "memory.h"
-#include "uuid.h"
-#include "network.h"
-#include "util.h"
-#include "virterror_internal.h"
-#include "command.h"
-#include "ignore-value.h"
-
-#define VIR_FROM_THIS VIR_FROM_NONE
-#define virSocketError(code, ...) \
- virReportErrorHelper(VIR_FROM_THIS, code, __FILE__, \
- __FUNCTION__, __LINE__, __VA_ARGS__)
-
-/*
- * Helpers to extract the IP arrays from the virSocketAddrPtr
- * That part is the less portable of the module
- */
-typedef unsigned char virSocketAddrIPv4[4];
-typedef virSocketAddrIPv4 *virSocketAddrIPv4Ptr;
-typedef unsigned short virSocketAddrIPv6[8];
-typedef virSocketAddrIPv6 *virSocketAddrIPv6Ptr;
-
-static int virSocketAddrGetIPv4Addr(virSocketAddrPtr addr, virSocketAddrIPv4Ptr tab) {
- unsigned long val;
- int i;
-
- if ((addr == NULL) || (tab == NULL) || (addr->data.stor.ss_family != AF_INET))
- return(-1);
-
- val = ntohl(addr->data.inet4.sin_addr.s_addr);
-
- for (i = 0;i < 4;i++) {
- (*tab)[3 - i] = val & 0xFF;
- val >>= 8;
- }
-
- return(0);
-}
-
-static int virSocketAddrGetIPv6Addr(virSocketAddrPtr addr, virSocketAddrIPv6Ptr tab) {
- int i;
-
- if ((addr == NULL) || (tab == NULL) || (addr->data.stor.ss_family != AF_INET6))
- return(-1);
-
- for (i = 0;i < 8;i++) {
- (*tab)[i] = ((addr->data.inet6.sin6_addr.s6_addr[2 * i] << 8) |
- addr->data.inet6.sin6_addr.s6_addr[2 * i + 1]);
- }
-
- return(0);
-}
-
-/**
- * virSocketAddrParse:
- * @val: a numeric network address IPv4 or IPv6
- * @addr: where to store the return value, optional.
- * @family: address family to pass down to getaddrinfo
- *
- * Mostly a wrapper for getaddrinfo() extracting the address storage
- * from the numeric string like 1.2.3.4 or 2001:db8:85a3:0:0:8a2e:370:7334
- *
- * Returns the length of the network address or -1 in case of error.
- */
-int virSocketAddrParse(virSocketAddrPtr addr, const char *val, int family) {
- int len;
- struct addrinfo hints;
- struct addrinfo *res = NULL;
- int err;
-
- if (val == NULL) {
- virSocketError(VIR_ERR_INVALID_ARG, "%s", _("Missing
address"));
- return -1;
- }
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = family;
- hints.ai_flags = AI_NUMERICHOST;
- if ((err = getaddrinfo(val, NULL, &hints, &res)) != 0) {
- virSocketError(VIR_ERR_SYSTEM_ERROR,
- _("Cannot parse socket address '%s': %s"),
- val, gai_strerror(err));
- return -1;
- }
-
- if (res == NULL) {
- virSocketError(VIR_ERR_SYSTEM_ERROR,
- _("No socket addresses found for '%s'"),
- val);
- return -1;
- }
-
- len = res->ai_addrlen;
- if (addr != NULL) {
- memcpy(&addr->data.stor, res->ai_addr, len);
- addr->len = res->ai_addrlen;
- }
-
- freeaddrinfo(res);
- return(len);
-}
-
-/*
- * virSocketAddrParseIPv4:
- * @val: an IPv4 numeric address
- * @addr: the location to store the result
- *
- * Extract the address storage from an IPv4 numeric address
- *
- * Returns the length of the network address or -1 in case of error.
- */
-int
-virSocketAddrParseIPv4(virSocketAddrPtr addr, const char *val) {
- return virSocketAddrParse(addr, val, AF_INET);
-}
-
-/*
- * virSocketAddrParseIPv6:
- * @val: an IPv6 numeric address
- * @addr: the location to store the result
- *
- * Extract the address storage from an IPv6 numeric address
- *
- * Returns the length of the network address or -1 in case of error.
- */
-int
-virSocketAddrParseIPv6(virSocketAddrPtr addr, const char *val) {
- return virSocketAddrParse(addr, val, AF_INET6);
-}
-
-/*
- * virSocketAddrFormat:
- * @addr: an initialized virSocketAddrPtr
- *
- * Returns a string representation of the given address
- * Returns NULL on any error
- * Caller must free the returned string
- */
-char *
-virSocketAddrFormat(virSocketAddrPtr addr) {
- return virSocketAddrFormatFull(addr, false, NULL);
-}
-
-
-/*
- * virSocketAddrFormatFull:
- * @addr: an initialized virSocketAddrPtr
- * @withService: if true, then service info is appended
- * @separator: separator between hostname & service.
- *
- * Returns a string representation of the given address
- * Returns NULL on any error
- * Caller must free the returned string
- */
-char *
-virSocketAddrFormatFull(virSocketAddrPtr addr,
- bool withService,
- const char *separator)
-{
- char host[NI_MAXHOST], port[NI_MAXSERV];
- char *addrstr;
- int err;
-
- if (addr == NULL) {
- virSocketError(VIR_ERR_INVALID_ARG, "%s", _("Missing
address"));
- return NULL;
- }
-
- /* Short-circuit since getnameinfo doesn't work
- * nicely for UNIX sockets */
- if (addr->data.sa.sa_family == AF_UNIX) {
- if (withService) {
- if (virAsprintf(&addrstr, "127.0.0.1%s0",
- separator ? separator : ":") < 0)
- goto no_memory;
- } else {
- if (!(addrstr = strdup("127.0.0.1")))
- goto no_memory;
- }
- return addrstr;
- }
-
- if ((err = getnameinfo(&addr->data.sa,
- addr->len,
- host, sizeof(host),
- port, sizeof(port),
- NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
- virSocketError(VIR_ERR_SYSTEM_ERROR,
- _("Cannot convert socket address to string: %s"),
- gai_strerror(err));
- return NULL;
- }
-
- if (withService) {
- if (virAsprintf(&addrstr, "%s%s%s", host, separator, port) == -1)
- goto no_memory;
- } else {
- if (!(addrstr = strdup(host)))
- goto no_memory;
- }
-
- return addrstr;
-
-no_memory:
- virReportOOMError();
- return NULL;
-}
-
-
-/*
- * virSocketAddrSetPort:
- * @addr: an initialized virSocketAddrPtr
- * @port: the port number to set
- *
- * Set the transport layer port of the given virtSocketAddr
- *
- * Returns 0 on success, -1 on failure
- */
-int
-virSocketAddrSetPort(virSocketAddrPtr addr, int port) {
- if (addr == NULL)
- return -1;
-
- port = htons(port);
-
- if(addr->data.stor.ss_family == AF_INET) {
- addr->data.inet4.sin_port = port;
- }
-
- else if(addr->data.stor.ss_family == AF_INET6) {
- addr->data.inet6.sin6_port = port;
- }
-
- else {
- return -1;
- }
-
- return 0;
-}
-
-/*
- * virSocketGetPort:
- * @addr: an initialized virSocketAddrPtr
- *
- * Returns the transport layer port of the given virtSocketAddr
- * Returns -1 if @addr is invalid
- */
-int
-virSocketAddrGetPort(virSocketAddrPtr addr) {
- if (addr == NULL)
- return -1;
-
- if(addr->data.stor.ss_family == AF_INET) {
- return ntohs(addr->data.inet4.sin_port);
- }
-
- else if(addr->data.stor.ss_family == AF_INET6) {
- return ntohs(addr->data.inet6.sin6_port);
- }
-
- return -1;
-}
-
-/**
- * virSocketAddrIsNetmask:
- * @netmask: the netmask address
- *
- * Check that @netmask is a proper network mask
- *
- * Returns 0 in case of success and -1 in case of error
- */
-int virSocketAddrIsNetmask(virSocketAddrPtr netmask) {
- int n = virSocketAddrGetNumNetmaskBits(netmask);
- if (n < 0)
- return -1;
- return 0;
-}
-
-/**
- * virSocketAddrMask:
- * @addr: address that needs to be masked
- * @netmask: the netmask address
- * @network: where to store the result, can be same as @addr
- *
- * Mask off the host bits of @addr according to @netmask, turning it
- * into a network address.
- *
- * Returns 0 in case of success, or -1 on error.
- */
-int
-virSocketAddrMask(const virSocketAddrPtr addr,
- const virSocketAddrPtr netmask,
- virSocketAddrPtr network)
-{
- if (addr->data.stor.ss_family != netmask->data.stor.ss_family) {
- network->data.stor.ss_family = AF_UNSPEC;
- return -1;
- }
-
- if (addr->data.stor.ss_family == AF_INET) {
- network->data.inet4.sin_addr.s_addr
- = (addr->data.inet4.sin_addr.s_addr
- & netmask->data.inet4.sin_addr.s_addr);
- network->data.inet4.sin_port = 0;
- network->data.stor.ss_family = AF_INET;
- network->len = addr->len;
- return 0;
- }
- if (addr->data.stor.ss_family == AF_INET6) {
- int ii;
- for (ii = 0; ii < 16; ii++) {
- network->data.inet6.sin6_addr.s6_addr[ii]
- = (addr->data.inet6.sin6_addr.s6_addr[ii]
- & netmask->data.inet6.sin6_addr.s6_addr[ii]);
- }
- network->data.inet6.sin6_port = 0;
- network->data.stor.ss_family = AF_INET6;
- network->len = addr->len;
- return 0;
- }
- network->data.stor.ss_family = AF_UNSPEC;
- return -1;
-}
-
-/**
- * virSocketAddrMaskByPrefix:
- * @addr: address that needs to be masked
- * @prefix: prefix (# of 1 bits) of netmask to apply
- * @network: where to store the result, can be same as @addr
- *
- * Mask off the host bits of @addr according to @prefix, turning it
- * into a network address.
- *
- * Returns 0 in case of success, or -1 on error.
- */
-int
-virSocketAddrMaskByPrefix(const virSocketAddrPtr addr,
- unsigned int prefix,
- virSocketAddrPtr network)
-{
- virSocketAddr netmask;
-
- if (virSocketAddrPrefixToNetmask(prefix, &netmask,
- addr->data.stor.ss_family) < 0) {
- network->data.stor.ss_family = AF_UNSPEC;
- return -1;
- }
-
- return virSocketAddrMask(addr, &netmask, network);
-}
-
-/**
- * virSocketAddrBroadcast:
- * @addr: address that needs to be turned into broadcast address (IPv4 only)
- * @netmask: the netmask address
- * @broadcast: virSocketAddr to recieve the broadcast address
- *
- * Mask ON the host bits of @addr according to @netmask, turning it
- * into a broadcast address.
- *
- * Returns 0 in case of success, or -1 on error.
- */
-int
-virSocketAddrBroadcast(const virSocketAddrPtr addr,
- const virSocketAddrPtr netmask,
- virSocketAddrPtr broadcast)
-{
- if ((addr->data.stor.ss_family != AF_INET) ||
- (netmask->data.stor.ss_family != AF_INET)) {
- broadcast->data.stor.ss_family = AF_UNSPEC;
- return -1;
- }
-
- broadcast->data.stor.ss_family = AF_INET;
- broadcast->len = addr->len;
- broadcast->data.inet4.sin_addr.s_addr
- = (addr->data.inet4.sin_addr.s_addr
- | ~netmask->data.inet4.sin_addr.s_addr);
- return 0;
-}
-
-/**
- * virSocketAddrBroadcastByPrefix:
- * @addr: address that needs to be turned into broadcast address (IPv4 only)
- * @prefix: prefix (# of 1 bits) of netmask to apply
- * @broadcast: virSocketAddr to recieve the broadcast address
- *
- * Mask off the host bits of @addr according to @prefix, turning it
- * into a network address.
- *
- * Returns 0 in case of success, or -1 on error.
- */
-int
-virSocketAddrBroadcastByPrefix(const virSocketAddrPtr addr,
- unsigned int prefix,
- virSocketAddrPtr broadcast)
-{
- virSocketAddr netmask;
-
- if (virSocketAddrPrefixToNetmask(prefix, &netmask,
- addr->data.stor.ss_family) < 0)
- return -1;
-
- return virSocketAddrBroadcast(addr, &netmask, broadcast);
-}
-
-/**
- * virSocketCheckNetmask:
- * @addr1: a first network address
- * @addr2: a second network address
- * @netmask: the netmask address
- *
- * Check that @addr1 and @addr2 pertain to the same @netmask address
- * range and returns the size of the range
- *
- * Returns 1 in case of success and 0 in case of failure and
- * -1 in case of error
- */
-int virSocketAddrCheckNetmask(virSocketAddrPtr addr1, virSocketAddrPtr addr2,
- virSocketAddrPtr netmask) {
- int i;
-
- if ((addr1 == NULL) || (addr2 == NULL) || (netmask == NULL))
- return(-1);
- if ((addr1->data.stor.ss_family != addr2->data.stor.ss_family) ||
- (addr1->data.stor.ss_family != netmask->data.stor.ss_family))
- return(-1);
-
- if (virSocketAddrIsNetmask(netmask) != 0)
- return(-1);
-
- if (addr1->data.stor.ss_family == AF_INET) {
- virSocketAddrIPv4 t1, t2, tm;
-
- if ((virSocketAddrGetIPv4Addr(addr1, &t1) < 0) ||
- (virSocketAddrGetIPv4Addr(addr2, &t2) < 0) ||
- (virSocketAddrGetIPv4Addr(netmask, &tm) < 0))
- return(-1);
-
- for (i = 0;i < 4;i++) {
- if ((t1[i] & tm[i]) != (t2[i] & tm[i]))
- return(0);
- }
-
- } else if (addr1->data.stor.ss_family == AF_INET6) {
- virSocketAddrIPv6 t1, t2, tm;
-
- if ((virSocketAddrGetIPv6Addr(addr1, &t1) < 0) ||
- (virSocketAddrGetIPv6Addr(addr2, &t2) < 0) ||
- (virSocketAddrGetIPv6Addr(netmask, &tm) < 0))
- return(-1);
-
- for (i = 0;i < 8;i++) {
- if ((t1[i] & tm[i]) != (t2[i] & tm[i]))
- return(0);
- }
-
- } else {
- return(-1);
- }
- return(1);
-}
-
-/**
- * virSocketGetRange:
- * @start: start of an IP range
- * @end: end of an IP range
- *
- * Check the order of the 2 addresses and compute the range, this
- * will return 1 for identical addresses. Errors can come from incompatible
- * addresses type, excessive range (>= 2^^16) where the two addresses are
- * unrelated or inverted start and end.
- *
- * Returns the size of the range or -1 in case of failure
- */
-int virSocketAddrGetRange(virSocketAddrPtr start, virSocketAddrPtr end) {
- int ret = 0, i;
-
- if ((start == NULL) || (end == NULL))
- return(-1);
- if (start->data.stor.ss_family != end->data.stor.ss_family)
- return(-1);
-
- if (start->data.stor.ss_family == AF_INET) {
- virSocketAddrIPv4 t1, t2;
-
- if ((virSocketAddrGetIPv4Addr(start, &t1) < 0) ||
- (virSocketAddrGetIPv4Addr(end, &t2) < 0))
- return(-1);
-
- for (i = 0;i < 2;i++) {
- if (t1[i] != t2[i])
- return(-1);
- }
- ret = (t2[2] - t1[2]) * 256 + (t2[3] - t1[3]);
- if (ret < 0)
- return(-1);
- ret++;
- } else if (start->data.stor.ss_family == AF_INET6) {
- virSocketAddrIPv6 t1, t2;
-
- if ((virSocketAddrGetIPv6Addr(start, &t1) < 0) ||
- (virSocketAddrGetIPv6Addr(end, &t2) < 0))
- return(-1);
-
- for (i = 0;i < 7;i++) {
- if (t1[i] != t2[i])
- return(-1);
- }
- ret = t2[7] - t1[7];
- if (ret < 0)
- return(-1);
- ret++;
- } else {
- return(-1);
- }
- return(ret);
-}
-
-
-/**
- * virSocketAddrGetNumNetmaskBits
- * @netmask: the presumed netmask
- *
- * Get the number of netmask bits in a netmask.
- *
- * Returns the number of bits in the netmask or -1 if an error occurred
- * or the netmask is invalid.
- */
-int virSocketAddrGetNumNetmaskBits(const virSocketAddrPtr netmask)
-{
- int i, j;
- int c = 0;
-
- if (netmask->data.stor.ss_family == AF_INET) {
- virSocketAddrIPv4 tm;
- uint8_t bit;
-
- if (virSocketAddrGetIPv4Addr(netmask, &tm) < 0)
- return -1;
-
- for (i = 0; i < 4; i++)
- if (tm[i] == 0xff)
- c += 8;
- else
- break;
-
- if (c == 8 * 4)
- return c;
-
- j = i << 3;
- while (j < (8 * 4)) {
- bit = 1 << (7 - (j & 7));
- if ((tm[j >> 3] & bit)) {
- c++;
- } else
- break;
- j++;
- }
-
- while (j < (8 * 4)) {
- bit = 1 << (7 - (j & 7));
- if ((tm[j >> 3] & bit))
- return -1;
- j++;
- }
-
- return c;
- } else if (netmask->data.stor.ss_family == AF_INET6) {
- virSocketAddrIPv6 tm;
- uint16_t bit;
-
- if (virSocketAddrGetIPv6Addr(netmask, &tm) < 0)
- return -1;
-
- for (i = 0; i < 8; i++)
- if (tm[i] == 0xffff)
- c += 16;
- else
- break;
-
- if (c == 16 * 8)
- return c;
-
- j = i << 4;
- while (j < (16 * 8)) {
- bit = 1 << (15 - (j & 0xf));
- if ((tm[j >> 4] & bit)) {
- c++;
- } else
- break;
- j++;
- }
-
- while (j < (16 * 8)) {
- bit = 1 << (15 - (j & 0xf));
- if ((tm[j >> 4]) & bit)
- return -1;
- j++;
- }
-
- return c;
- }
- return -1;
-}
-
-/**
- * virSocketPrefixToNetmask:
- * @prefix: number of 1 bits to put in the netmask
- * @netmask: address to fill in with the desired netmask
- * @family: family of the address (AF_INET or AF_INET6 only)
- *
- * given @prefix and @family, fill in @netmask with a netmask
- * (eg 255.255.255.0).
- *
- * Returns 0 on success or -1 on error.
- */
-
-int
-virSocketAddrPrefixToNetmask(unsigned int prefix,
- virSocketAddrPtr netmask,
- int family)
-{
- int result = -1;
-
- netmask->data.stor.ss_family = AF_UNSPEC; /* assume failure */
-
- if (family == AF_INET) {
- int ip;
-
- if (prefix > 32)
- goto error;
-
- ip = prefix ? ~((1 << (32 - prefix)) - 1) : 0;
- netmask->data.inet4.sin_addr.s_addr = htonl(ip);
- netmask->data.stor.ss_family = AF_INET;
- result = 0;
-
- } else if (family == AF_INET6) {
- int ii = 0;
-
- if (prefix > 128)
- goto error;
-
- while (prefix >= 8) {
- /* do as much as possible an entire byte at a time */
- netmask->data.inet6.sin6_addr.s6_addr[ii++] = 0xff;
- prefix -= 8;
- }
- if (prefix > 0) {
- /* final partial byte */
- netmask->data.inet6.sin6_addr.s6_addr[ii++]
- = ~((1 << (8 - prefix)) -1);
- }
- while (ii < 16) {
- /* zerofill remainder in case it wasn't initialized */
- netmask->data.inet6.sin6_addr.s6_addr[ii++] = 0;
- }
- netmask->data.stor.ss_family = AF_INET6;
- result = 0;
- }
-
-error:
- return result;
-}
-
-/* virtualPortProfile utilities */
-
-VIR_ENUM_IMPL(virNetDevVPort, VIR_NETDEV_VPORT_PROFILE_LAST,
- "none",
- "802.1Qbg",
- "802.1Qbh")
-
-
-virNetDevVPortProfilePtr
-virNetDevVPortProfileParse(xmlNodePtr node)
-{
- char *virtPortType;
- char *virtPortManagerID = NULL;
- char *virtPortTypeID = NULL;
- char *virtPortTypeIDVersion = NULL;
- char *virtPortInstanceID = NULL;
- char *virtPortProfileID = NULL;
- virNetDevVPortProfilePtr virtPort = NULL;
- xmlNodePtr cur = node->children;
-
- if (VIR_ALLOC(virtPort) < 0) {
- virReportOOMError();
- return NULL;
- }
-
- virtPortType = virXMLPropString(node, "type");
- if (!virtPortType) {
- virSocketError(VIR_ERR_XML_ERROR, "%s",
- _("missing virtualportprofile type"));
- goto error;
- }
-
- if ((virtPortType = virNetDevVPortTypeFromString(virtPortType)) <= 0) {
- virSocketError(VIR_ERR_XML_ERROR,
- _("unknown virtualportprofile type %s"), virtPortType);
- goto error;
- }
-
- while (cur != NULL) {
- if (xmlStrEqual(cur->name, BAD_CAST "parameters")) {
-
- virtPortManagerID = virXMLPropString(cur, "managerid");
- virtPortTypeID = virXMLPropString(cur, "typeid");
- virtPortTypeIDVersion = virXMLPropString(cur, "typeidversion");
- virtPortInstanceID = virXMLPropString(cur, "instanceid");
- virtPortProfileID = virXMLPropString(cur, "profileid");
-
- break;
- }
-
- cur = cur->next;
- }
-
- switch (virtPort->virtPortType) {
- case VIR_NETDEV_VPORT_PROFILE_8021QBG:
- if (virtPortManagerID != NULL && virtPortTypeID != NULL
&&
- virtPortTypeIDVersion != NULL) {
- unsigned int val;
-
- if (virStrToLong_ui(virtPortManagerID, NULL, 0, &val)) {
- virSocketError(VIR_ERR_XML_ERROR, "%s",
- _("cannot parse value of managerid
parameter"));
- goto error;
- }
-
- if (val > 0xff) {
- virSocketError(VIR_ERR_XML_ERROR, "%s",
- _("value of managerid out of range"));
- goto error;
- }
-
- virtPort->u.virtPort8021Qbg.managerID = (uint8_t)val;
-
- if (virStrToLong_ui(virtPortTypeID, NULL, 0, &val)) {
- virSocketError(VIR_ERR_XML_ERROR, "%s",
- _("cannot parse value of typeid
parameter"));
- goto error;
- }
-
- if (val > 0xffffff) {
- virSocketError(VIR_ERR_XML_ERROR, "%s",
- _("value for typeid out of range"));
- goto error;
- }
-
- virtPort->u.virtPort8021Qbg.typeID = (uint32_t)val;
-
- if (virStrToLong_ui(virtPortTypeIDVersion, NULL, 0, &val)) {
- virSocketError(VIR_ERR_XML_ERROR, "%s",
- _("cannot parse value of typeidversion
parameter"));
- goto error;
- }
-
- if (val > 0xff) {
- virSocketError(VIR_ERR_XML_ERROR, "%s",
- _("value of typeidversion out of
range"));
- goto error;
- }
-
- virtPort->u.virtPort8021Qbg.typeIDVersion = (uint8_t)val;
-
- if (virtPortInstanceID != NULL) {
- if (virUUIDParse(virtPortInstanceID,
- virtPort->u.virtPort8021Qbg.instanceID)) {
- virSocketError(VIR_ERR_XML_ERROR, "%s",
- _("cannot parse instanceid parameter as a
uuid"));
- goto error;
- }
- } else {
- if (virUUIDGenerate(virtPort->u.virtPort8021Qbg.instanceID)) {
- virSocketError(VIR_ERR_XML_ERROR, "%s",
- _("cannot generate a random uuid for
instanceid"));
- goto error;
- }
- }
-
- virtPort->virtPortType = VIR_NETDEV_VPORT_PROFILE_8021QBG;
-
- } else {
- virSocketError(VIR_ERR_XML_ERROR, "%s",
- _("a parameter is missing for 802.1Qbg
description"));
- goto error;
- }
- break;
-
- case VIR_NETDEV_VPORT_PROFILE_8021QBH:
- if (virtPortProfileID != NULL) {
- if (virStrcpyStatic(virtPort->u.virtPort8021Qbh.profileID,
- virtPortProfileID) != NULL) {
- virtPort->virtPortType = VIR_NETDEV_VPORT_PROFILE_8021QBH;
- } else {
- virSocketError(VIR_ERR_XML_ERROR, "%s",
- _("profileid parameter too long"));
- goto error;
- }
- } else {
- virSocketError(VIR_ERR_XML_ERROR, "%s",
- _("profileid parameter is missing for 802.1Qbh
descripion"));
- goto error;
- }
- break;
-
- default:
- virSocketError(VIR_ERR_XML_ERROR,
- _("unexpected virtualport type %d"),
virtPort->virtPortType);
- goto error;
- }
-
-cleanup:
- VIR_FREE(virtPortManagerID);
- VIR_FREE(virtPortTypeID);
- VIR_FREE(virtPortTypeIDVersion);
- VIR_FREE(virtPortInstanceID);
- VIR_FREE(virtPortProfileID);
- VIR_FREE(virtPortType);
-
- return virtPort;
-
-error:
- VIR_FREE(virtPort);
- goto cleanup;
-}
-
-bool
-virNetDevVPortProfileEqual(virNetDevVPortProfilePtr a, virNetDevVPortProfilePtr b)
-{
- /* NULL resistant */
- if (!a && !b)
- return true;
-
- if (!a || !b)
- return false;
-
- if (a->virtPortType != b->virtPortType)
- return false;
-
- switch (a->virtPortType) {
- case VIR_NETDEV_VPORT_PROFILE_NONE:
- break;
-
- case VIR_NETDEV_VPORT_PROFILE_8021QBG:
- if (a->u.virtPort8021Qbg.managerID != b->u.virtPort8021Qbg.managerID ||
- a->u.virtPort8021Qbg.typeID != b->u.virtPort8021Qbg.typeID ||
- a->u.virtPort8021Qbg.typeIDVersion !=
b->u.virtPort8021Qbg.typeIDVersion ||
- memcmp(a->u.virtPort8021Qbg.instanceID,
b->u.virtPort8021Qbg.instanceID, VIR_UUID_BUFLEN) != 0)
- return false;
- break;
-
- case VIR_NETDEV_VPORT_PROFILE_8021QBH:
- if (STRNEQ(a->u.virtPort8021Qbh.profileID,
b->u.virtPort8021Qbh.profileID))
- return false;
- break;
-
- default:
- break;
- }
-
- return true;
-}
-
-
-int
-virNetDevVPortProfileFormat(virNetDevVPortProfilePtr virtPort,
- virBufferPtr buf)
-{
- char uuidstr[VIR_UUID_STRING_BUFLEN];
-
- if (!virtPort || virtPort->virtPortType == VIR_NETDEV_VPORT_PROFILE_NONE)
- return 0;
-
- virBufferAsprintf(buf, "<virtualport type='%s'>\n",
- virNetDevVPortTypeToString(virtPort->virtPortType));
-
- switch (virtPort->virtPortType) {
- case VIR_NETDEV_VPORT_PROFILE_8021QBG:
- virUUIDFormat(virtPort->u.virtPort8021Qbg.instanceID,
- uuidstr);
- virBufferAsprintf(buf,
- " <parameters managerid='%d'
typeid='%d' "
- "typeidversion='%d'
instanceid='%s'/>\n",
- virtPort->u.virtPort8021Qbg.managerID,
- virtPort->u.virtPort8021Qbg.typeID,
- virtPort->u.virtPort8021Qbg.typeIDVersion,
- uuidstr);
- break;
-
- case VIR_NETDEV_VPORT_PROFILE_8021QBH:
- virBufferAsprintf(buf,
- " <parameters profileid='%s'/>\n",
- virtPort->u.virtPort8021Qbh.profileID);
- break;
-
- default:
- virSocketError(VIR_ERR_XML_ERROR,
- _("unexpected virtualport type %d"),
virtPort->virtPortType);
- return -1;
- }
-
- virBufferAddLit(buf, "</virtualport>\n");
- return 0;
-}
-
-static int
-virNetDevBandwidthParseRate(xmlNodePtr node, virNetDevBandwidthRatePtr rate)
-{
- int ret = -1;
- char *average = NULL;
- char *peak = NULL;
- char *burst = NULL;
-
- if (!node || !rate) {
- virSocketError(VIR_ERR_INVALID_ARG, "%s",
- _("invalid argument supplied"));
- return -1;
- }
-
- average = virXMLPropString(node, "average");
- peak = virXMLPropString(node, "peak");
- burst = virXMLPropString(node, "burst");
-
- if (average) {
- if (virStrToLong_ull(average, NULL, 10, &rate->average) < 0) {
- virSocketError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("could not convert %s"),
- average);
- goto cleanup;
- }
- } else {
- virSocketError(VIR_ERR_XML_DETAIL, "%s",
- _("Missing mandatory average attribute"));
- goto cleanup;
- }
-
- if (peak && virStrToLong_ull(peak, NULL, 10, &rate->peak) < 0) {
- virSocketError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("could not convert %s"),
- peak);
- goto cleanup;
- }
-
- if (burst && virStrToLong_ull(burst, NULL, 10, &rate->burst) < 0)
{
- virSocketError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("could not convert %s"),
- burst);
- goto cleanup;
- }
-
- ret = 0;
-
-cleanup:
- VIR_FREE(average);
- VIR_FREE(peak);
- VIR_FREE(burst);
-
- return ret;
-}
-
-/**
- * virNetDevBandwidthParse:
- * @node: XML node
- *
- * Parse bandwidth XML and return pointer to structure
- *
- * Returns !NULL on success, NULL on error.
- */
-virNetDevBandwidthPtr
-virNetDevBandwidthParse(xmlNodePtr node)
-{
- virNetDevBandwidthPtr def = NULL;
- xmlNodePtr cur = node->children;
- xmlNodePtr in = NULL, out = NULL;
-
- if (VIR_ALLOC(def) < 0) {
- virReportOOMError();
- return NULL;
- }
-
- if (!node || !xmlStrEqual(node->name, BAD_CAST "bandwidth")) {
- virSocketError(VIR_ERR_INVALID_ARG, "%s",
- _("invalid argument supplied"));
- goto error;
- }
-
- while (cur) {
- if (cur->type == XML_ELEMENT_NODE) {
- if (xmlStrEqual(cur->name, BAD_CAST "inbound")) {
- if (in) {
- virSocketError(VIR_ERR_XML_DETAIL, "%s",
- _("Only one child <inbound> "
- "element allowed"));
- goto error;
- }
- in = cur;
- } else if (xmlStrEqual(cur->name, BAD_CAST "outbound")) {
- if (out) {
- virSocketError(VIR_ERR_XML_DETAIL, "%s",
- _("Only one child <outbound> "
- "element allowed"));
- goto error;
- }
- out = cur;
- }
- /* Silently ignore unknown elements */
- }
- cur = cur->next;
- }
-
- if (in) {
- if (VIR_ALLOC(def->in) < 0) {
- virReportOOMError();
- goto error;
- }
-
- if (virNetDevBandwidthParseRate(in, def->in) < 0) {
- /* helper reported error for us */
- goto error;
- }
- }
-
- if (out) {
- if (VIR_ALLOC(def->out) < 0) {
- virReportOOMError();
- goto error;
- }
-
- if (virNetDevBandwidthParseRate(out, def->out) < 0) {
- /* helper reported error for us */
- goto error;
- }
- }
-
- return def;
-
-error:
- virNetDevBandwidthFree(def);
- return NULL;
-}
-
-void
-virNetDevBandwidthFree(virNetDevBandwidthPtr def)
-{
- if (!def)
- return;
-
- VIR_FREE(def->in);
- VIR_FREE(def->out);
- VIR_FREE(def);
-}
-
-static int
-virNetDevBandwidthRateFormat(virNetDevBandwidthRatePtr def,
- virBufferPtr buf,
- const char *elem_name)
-{
- if (!buf || !elem_name)
- return -1;
- if (!def)
- return 0;
-
- if (def->average) {
- virBufferAsprintf(buf, " <%s average='%llu'", elem_name,
- def->average);
-
- if (def->peak)
- virBufferAsprintf(buf, " peak='%llu'", def->peak);
-
- if (def->burst)
- virBufferAsprintf(buf, " burst='%llu'", def->burst);
- virBufferAddLit(buf, "/>\n");
- }
-
- return 0;
-}
-
-/**
- * virNetDevBandwidthDefFormat:
- * @def: Data source
- * @buf: Buffer to print to
- *
- * Formats bandwidth and prepend each line with @indent.
- * @buf may use auto-indentation.
- *
- * Returns 0 on success, else -1.
- */
-int
-virNetDevBandwidthFormat(virNetDevBandwidthPtr def, virBufferPtr buf)
-{
- int ret = -1;
-
- if (!buf)
- goto cleanup;
-
- if (!def) {
- ret = 0;
- goto cleanup;
- }
-
- virBufferAddLit(buf, "<bandwidth>\n");
- if (virNetDevBandwidthRateFormat(def->in, buf, "inbound") < 0 ||
- virNetDevBandwidthRateFormat(def->out, buf, "outbound") < 0)
- goto cleanup;
- virBufferAddLit(buf, "</bandwidth>\n");
-
- ret = 0;
-
-cleanup:
- return ret;
-}
-
-/**
- * virNetDevBandwidthSet:
- * @ifname: on which interface
- * @bandwidth: rates to set (may be NULL)
- *
- * This function enables QoS on specified interface
- * and set given traffic limits for both, incoming
- * and outgoing traffic. Any previous setting get
- * overwritten.
- *
- * Return 0 on success, -1 otherwise.
- */
-int
-virNetDevBandwidthSet(const char *ifname,
- virNetDevBandwidthPtr bandwidth)
-{
- int ret = -1;
- virCommandPtr cmd = NULL;
- char *average = NULL;
- char *peak = NULL;
- char *burst = NULL;
-
- if (!bandwidth) {
- /* nothing to be enabled */
- ret = 0;
- goto cleanup;
- }
-
- ignore_value(virNetDevBandwidthClear(ifname));
-
- if (bandwidth->in) {
- if (virAsprintf(&average, "%llukbps", bandwidth->in->average)
< 0)
- goto cleanup;
- if (bandwidth->in->peak &&
- (virAsprintf(&peak, "%llukbps", bandwidth->in->peak) <
0))
- goto cleanup;
- if (bandwidth->in->burst &&
- (virAsprintf(&burst, "%llukb", bandwidth->in->burst) <
0))
- goto cleanup;
-
- cmd = virCommandNew(TC);
- virCommandAddArgList(cmd, "qdisc", "add", "dev",
ifname, "root",
- "handle", "1:", "htb",
"default", "1", NULL);
- if (virCommandRun(cmd, NULL) < 0)
- goto cleanup;
-
- virCommandFree(cmd);
- cmd = virCommandNew(TC);
- virCommandAddArgList(cmd,"class", "add", "dev",
ifname, "parent",
- "1:", "classid", "1:1",
"htb", NULL);
- virCommandAddArgList(cmd, "rate", average, NULL);
-
- if (peak)
- virCommandAddArgList(cmd, "ceil", peak, NULL);
- if (burst)
- virCommandAddArgList(cmd, "burst", burst, NULL);
-
- if (virCommandRun(cmd, NULL) < 0)
- goto cleanup;
-
- virCommandFree(cmd);
- cmd = virCommandNew(TC);
- virCommandAddArgList(cmd,"filter", "add",
"dev", ifname, "parent",
- "1:0", "protocol", "ip",
"handle", "1", "fw",
- "flowid", "1", NULL);
-
- if (virCommandRun(cmd, NULL) < 0)
- goto cleanup;
-
- VIR_FREE(average);
- VIR_FREE(peak);
- VIR_FREE(burst);
- }
-
- if (bandwidth->out) {
- if (virAsprintf(&average, "%llukbps",
bandwidth->out->average) < 0)
- goto cleanup;
- if (virAsprintf(&burst, "%llukb", bandwidth->out->burst ?
- bandwidth->out->burst : bandwidth->out->average) <
0)
- goto cleanup;
-
- virCommandFree(cmd);
- cmd = virCommandNew(TC);
- virCommandAddArgList(cmd, "qdisc", "add",
"dev", ifname,
- "ingress", NULL);
-
- if (virCommandRun(cmd, NULL) < 0)
- goto cleanup;
-
- virCommandFree(cmd);
- cmd = virCommandNew(TC);
- virCommandAddArgList(cmd, "filter", "add", "dev",
ifname, "parent",
- "ffff:", "protocol", "ip",
"u32", "match", "ip",
- "src", "0.0.0.0/0", "police",
"rate", average,
- "burst", burst, "mtu", burst,
"drop", "flowid",
- ":1", NULL);
-
- if (virCommandRun(cmd, NULL) < 0)
- goto cleanup;
- }
-
- ret = 0;
-
-cleanup:
- virCommandFree(cmd);
- VIR_FREE(average);
- VIR_FREE(peak);
- VIR_FREE(burst);
- return ret;
-}
-
-/**
- * virNetDevBandwidthClear:
- * @ifname: on which interface
- *
- * This function tries to disable QoS on specified interface
- * by deleting root and ingress qdisc. However, this may fail
- * if we try to remove the default one.
- *
- * Return 0 on success, -1 otherwise.
- */
-int
-virNetDevBandwidthClear(const char *ifname)
-{
- int ret = 0;
- virCommandPtr cmd = NULL;
-
- cmd = virCommandNew(TC);
- virCommandAddArgList(cmd, "qdisc", "del", "dev",
ifname, "root", NULL);
-
- if (virCommandRun(cmd, NULL) < 0)
- ret = -1;
-
- virCommandFree(cmd);
-
- cmd = virCommandNew(TC);
- virCommandAddArgList(cmd, "qdisc", "del", "dev",
ifname, "ingress", NULL);
-
- if (virCommandRun(cmd, NULL) < 0)
- ret = -1;
- virCommandFree(cmd);
-
- return ret;
-}
-
-/*
- * virNetDevBandwidthCopy:
- * @dest: destination
- * @src: source (may be NULL)
- *
- * Returns -1 on OOM error (which gets reported),
- * 0 otherwise.
- */
-int
-virNetDevBandwidthCopy(virNetDevBandwidthPtr *dest,
- const virNetDevBandwidthPtr src)
-{
- int ret = -1;
-
- *dest = NULL;
- if (!src) {
- /* nothing to be copied */
- return 0;
- }
-
- if (VIR_ALLOC(*dest) < 0) {
- virReportOOMError();
- goto cleanup;
- }
-
- if (src->in) {
- if (VIR_ALLOC((*dest)->in) < 0) {
- virReportOOMError();
- goto cleanup;
- }
- memcpy((*dest)->in, src->in, sizeof(*src->in));
- }
-
- if (src->out) {
- if (VIR_ALLOC((*dest)->out) < 0) {
- virReportOOMError();
- VIR_FREE((*dest)->in);
- goto cleanup;
- }
- memcpy((*dest)->out, src->out, sizeof(*src->out));
- }
-
- ret = 0;
-
-cleanup:
- if (ret < 0) {
- virNetDevBandwidthFree(*dest);
- *dest = NULL;
- }
- return ret;
-}
-
-bool
-virNetDevBandwidthEqual(virNetDevBandwidthPtr a,
- virNetDevBandwidthPtr b)
-{
- if (!a && !b)
- return true;
-
- if (!a || !b)
- return false;
-
- /* in */
- if (a->in->average != b->in->average ||
- a->in->peak != b->in->peak ||
- a->in->burst != b->in->burst)
- return false;
-
- /*out*/
- if (a->out->average != b->out->average ||
- a->out->peak != b->out->peak ||
- a->out->burst != b->out->burst)
- return false;
-
- return true;
-}
diff --git a/src/util/network.h b/src/util/network.h
deleted file mode 100644
index 98dfacc..0000000
--- a/src/util/network.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * network.h: network helper APIs for libvirt
- *
- * Copyright (C) 2009-2011 Red Hat, Inc.
- *
- * See COPYING.LIB for the License of this software
- *
- * Daniel Veillard <veillard(a)redhat.com>
- */
-
-#ifndef __VIR_NETWORK_H__
-# define __VIR_NETWORK_H__
-
-# include "internal.h"
-# include "buf.h"
-# include "util.h"
-
-# include <sys/types.h>
-# include <sys/socket.h>
-# ifdef HAVE_SYS_UN_H
-# include <sys/un.h>
-# endif
-# include <netdb.h>
-# include <netinet/in.h>
-# include <xml.h>
-
-typedef struct {
- union {
- struct sockaddr sa;
- struct sockaddr_storage stor;
- struct sockaddr_in inet4;
- struct sockaddr_in6 inet6;
-# ifdef HAVE_SYS_UN_H
- struct sockaddr_un un;
-# endif
- } data;
- socklen_t len;
-} virSocketAddr;
-
-# define VIR_SOCKET_ADDR_VALID(s) \
- ((s)->data.sa.sa_family != AF_UNSPEC)
-
-# define VIR_SOCKET_ADDR_IS_FAMILY(s, f) \
- ((s)->data.sa.sa_family == f)
-
-# define VIR_SOCKET_ADDR_FAMILY(s) \
- ((s)->data.sa.sa_family)
-
-typedef virSocketAddr *virSocketAddrPtr;
-
-typedef struct _virNetDevBandwidthRate virNetDevBandwidthRate;
-typedef virNetDevBandwidthRate *virNetDevBandwidthRatePtr;
-struct _virNetDevBandwidthRate {
- unsigned long long average; /* kbytes/s */
- unsigned long long peak; /* kbytes/s */
- unsigned long long burst; /* kbytes */
-};
-
-typedef struct _virNetDevBandwidth virNetDevBandwidth;
-typedef virNetDevBandwidth *virNetDevBandwidthPtr;
-struct _virNetDevBandwidth {
- virNetDevBandwidthRatePtr in, out;
-};
-
-int virSocketAddrParse(virSocketAddrPtr addr,
- const char *val,
- int family);
-
-int virSocketAddrParseIPv4(virSocketAddrPtr addr,
- const char *val);
-
-int virSocketAddrParseIPv6(virSocketAddrPtr addr,
- const char *val);
-
-char * virSocketAddrFormat(virSocketAddrPtr addr);
-char * virSocketAddrFormatFull(virSocketAddrPtr addr,
- bool withService,
- const char *separator);
-
-int virSocketAddrSetPort(virSocketAddrPtr addr, int port);
-
-int virSocketAddrGetPort(virSocketAddrPtr addr);
-
-int virSocketAddrGetRange(virSocketAddrPtr start,
- virSocketAddrPtr end);
-
-int virSocketAddrIsNetmask(virSocketAddrPtr netmask);
-
-int virSocketAddrCheckNetmask(virSocketAddrPtr addr1,
- virSocketAddrPtr addr2,
- virSocketAddrPtr netmask);
-int virSocketAddrMask(const virSocketAddrPtr addr,
- const virSocketAddrPtr netmask,
- virSocketAddrPtr network);
-int virSocketAddrMaskByPrefix(const virSocketAddrPtr addr,
- unsigned int prefix,
- virSocketAddrPtr network);
-int virSocketAddrBroadcast(const virSocketAddrPtr addr,
- const virSocketAddrPtr netmask,
- virSocketAddrPtr broadcast);
-int virSocketAddrBroadcastByPrefix(const virSocketAddrPtr addr,
- unsigned int prefix,
- virSocketAddrPtr broadcast);
-
-int virSocketAddrGetNumNetmaskBits(const virSocketAddrPtr netmask);
-int virSocketAddrPrefixToNetmask(unsigned int prefix,
- virSocketAddrPtr netmask,
- int family);
-
-/* virtualPortProfile utilities */
-# ifdef IFLA_VF_PORT_PROFILE_MAX
-# define LIBVIRT_IFLA_VF_PORT_PROFILE_MAX IFLA_VF_PORT_PROFILE_MAX
-# else
-# define LIBVIRT_IFLA_VF_PORT_PROFILE_MAX 40
-# endif
-
-enum virNetDevVPortProfile {
- VIR_NETDEV_VPORT_PROFILE_NONE,
- VIR_NETDEV_VPORT_PROFILE_8021QBG,
- VIR_NETDEV_VPORT_PROFILE_8021QBH,
-
- VIR_NETDEV_VPORT_PROFILE_LAST,
-};
-
-VIR_ENUM_DECL(virNetDevVPort)
-
-/* profile data for macvtap (VEPA) */
-typedef struct _virNetDevVPortProfile virNetDevVPortProfile;
-typedef virNetDevVPortProfile *virNetDevVPortProfilePtr;
-struct _virNetDevVPortProfile {
- enum virNetDevVPortProfile virtPortType;
- union {
- struct {
- uint8_t managerID;
- uint32_t typeID; /* 24 bit valid */
- uint8_t typeIDVersion;
- unsigned char instanceID[VIR_UUID_BUFLEN];
- } virtPort8021Qbg;
- struct {
- char profileID[LIBVIRT_IFLA_VF_PORT_PROFILE_MAX];
- } virtPort8021Qbh;
- } u;
-};
-
-
-virNetDevVPortProfilePtr
-virNetDevVPortProfileParse(xmlNodePtr node);
-
-int
-virNetDevVPortProfileFormat(virNetDevVPortProfilePtr virtPort,
- virBufferPtr buf);
-
-bool virNetDevVPortProfileEqual(virNetDevVPortProfilePtr a,
- virNetDevVPortProfilePtr b);
-
-virNetDevBandwidthPtr virNetDevBandwidthParse(xmlNodePtr node)
- ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
-void virNetDevBandwidthFree(virNetDevBandwidthPtr def);
-int virNetDevBandwidthFormat(virNetDevBandwidthPtr def,
- virBufferPtr buf)
- ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
-
-int virNetDevBandwidthSet(const char *ifname, virNetDevBandwidthPtr bandwidth)
- ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
-int virNetDevBandwidthClear(const char *ifname)
- ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
-int virNetDevBandwidthCopy(virNetDevBandwidthPtr *dest, const virNetDevBandwidthPtr src)
- ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
-
-bool virNetDevBandwidthEqual(virNetDevBandwidthPtr a, virNetDevBandwidthPtr b);
-
-
-#endif /* __VIR_NETWORK_H__ */
diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h
index cae98b7..5324b66 100644
--- a/src/util/virnetdev.h
+++ b/src/util/virnetdev.h
@@ -23,7 +23,7 @@
#ifndef __VIR_NETDEV_H__
# define __VIR_NETDEV_H__
-# include "network.h"
+# include "virsocketaddr.h"
int virNetDevExists(const char *brname)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
diff --git a/src/util/virnetdevbandwidth.c b/src/util/virnetdevbandwidth.c
new file mode 100644
index 0000000..10db1ff
--- /dev/null
+++ b/src/util/virnetdevbandwidth.c
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2009-2011 Red Hat, 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors:
+ * Michal Privoznik <mprivozn(a)redhat.com>
+ * Daniel P. Berrange <berrange(a)redhat.com>
+ */
+
+#include <config.h>
+
+#include "virnetdevbandwidth.h"
+#include "command.h"
+#include "memory.h"
+#include "virterror_internal.h"
+#include "ignore-value.h"
+
+#define VIR_FROM_THIS VIR_FROM_NONE
+
+void
+virNetDevBandwidthFree(virNetDevBandwidthPtr def)
+{
+ if (!def)
+ return;
+
+ VIR_FREE(def->in);
+ VIR_FREE(def->out);
+ VIR_FREE(def);
+}
+
+
+/**
+ * virNetDevBandwidthSet:
+ * @ifname: on which interface
+ * @bandwidth: rates to set (may be NULL)
+ *
+ * This function enables QoS on specified interface
+ * and set given traffic limits for both, incoming
+ * and outgoing traffic. Any previous setting get
+ * overwritten.
+ *
+ * Return 0 on success, -1 otherwise.
+ */
+int
+virNetDevBandwidthSet(const char *ifname,
+ virNetDevBandwidthPtr bandwidth)
+{
+ int ret = -1;
+ virCommandPtr cmd = NULL;
+ char *average = NULL;
+ char *peak = NULL;
+ char *burst = NULL;
+
+ if (!bandwidth) {
+ /* nothing to be enabled */
+ ret = 0;
+ goto cleanup;
+ }
+
+ ignore_value(virNetDevBandwidthClear(ifname));
+
+ if (bandwidth->in) {
+ if (virAsprintf(&average, "%llukbps", bandwidth->in->average)
< 0)
+ goto cleanup;
+ if (bandwidth->in->peak &&
+ (virAsprintf(&peak, "%llukbps", bandwidth->in->peak) <
0))
+ goto cleanup;
+ if (bandwidth->in->burst &&
+ (virAsprintf(&burst, "%llukb", bandwidth->in->burst) <
0))
+ goto cleanup;
+
+ cmd = virCommandNew(TC);
+ virCommandAddArgList(cmd, "qdisc", "add", "dev",
ifname, "root",
+ "handle", "1:", "htb",
"default", "1", NULL);
+ if (virCommandRun(cmd, NULL) < 0)
+ goto cleanup;
+
+ virCommandFree(cmd);
+ cmd = virCommandNew(TC);
+ virCommandAddArgList(cmd,"class", "add", "dev",
ifname, "parent",
+ "1:", "classid", "1:1",
"htb", NULL);
+ virCommandAddArgList(cmd, "rate", average, NULL);
+
+ if (peak)
+ virCommandAddArgList(cmd, "ceil", peak, NULL);
+ if (burst)
+ virCommandAddArgList(cmd, "burst", burst, NULL);
+
+ if (virCommandRun(cmd, NULL) < 0)
+ goto cleanup;
+
+ virCommandFree(cmd);
+ cmd = virCommandNew(TC);
+ virCommandAddArgList(cmd,"filter", "add",
"dev", ifname, "parent",
+ "1:0", "protocol", "ip",
"handle", "1", "fw",
+ "flowid", "1", NULL);
+
+ if (virCommandRun(cmd, NULL) < 0)
+ goto cleanup;
+
+ VIR_FREE(average);
+ VIR_FREE(peak);
+ VIR_FREE(burst);
+ }
+
+ if (bandwidth->out) {
+ if (virAsprintf(&average, "%llukbps",
bandwidth->out->average) < 0)
+ goto cleanup;
+ if (virAsprintf(&burst, "%llukb", bandwidth->out->burst ?
+ bandwidth->out->burst : bandwidth->out->average) <
0)
+ goto cleanup;
+
+ virCommandFree(cmd);
+ cmd = virCommandNew(TC);
+ virCommandAddArgList(cmd, "qdisc", "add",
"dev", ifname,
+ "ingress", NULL);
+
+ if (virCommandRun(cmd, NULL) < 0)
+ goto cleanup;
+
+ virCommandFree(cmd);
+ cmd = virCommandNew(TC);
+ virCommandAddArgList(cmd, "filter", "add", "dev",
ifname, "parent",
+ "ffff:", "protocol", "ip",
"u32", "match", "ip",
+ "src", "0.0.0.0/0", "police",
"rate", average,
+ "burst", burst, "mtu", burst,
"drop", "flowid",
+ ":1", NULL);
+
+ if (virCommandRun(cmd, NULL) < 0)
+ goto cleanup;
+ }
+
+ ret = 0;
+
+cleanup:
+ virCommandFree(cmd);
+ VIR_FREE(average);
+ VIR_FREE(peak);
+ VIR_FREE(burst);
+ return ret;
+}
+
+/**
+ * virNetDevBandwidthClear:
+ * @ifname: on which interface
+ *
+ * This function tries to disable QoS on specified interface
+ * by deleting root and ingress qdisc. However, this may fail
+ * if we try to remove the default one.
+ *
+ * Return 0 on success, -1 otherwise.
+ */
+int
+virNetDevBandwidthClear(const char *ifname)
+{
+ int ret = 0;
+ virCommandPtr cmd = NULL;
+
+ cmd = virCommandNew(TC);
+ virCommandAddArgList(cmd, "qdisc", "del", "dev",
ifname, "root", NULL);
+
+ if (virCommandRun(cmd, NULL) < 0)
+ ret = -1;
+
+ virCommandFree(cmd);
+
+ cmd = virCommandNew(TC);
+ virCommandAddArgList(cmd, "qdisc", "del", "dev",
ifname, "ingress", NULL);
+
+ if (virCommandRun(cmd, NULL) < 0)
+ ret = -1;
+ virCommandFree(cmd);
+
+ return ret;
+}
+
+/*
+ * virNetDevBandwidthCopy:
+ * @dest: destination
+ * @src: source (may be NULL)
+ *
+ * Returns -1 on OOM error (which gets reported),
+ * 0 otherwise.
+ */
+int
+virNetDevBandwidthCopy(virNetDevBandwidthPtr *dest,
+ const virNetDevBandwidthPtr src)
+{
+ int ret = -1;
+
+ *dest = NULL;
+ if (!src) {
+ /* nothing to be copied */
+ return 0;
+ }
+
+ if (VIR_ALLOC(*dest) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (src->in) {
+ if (VIR_ALLOC((*dest)->in) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ memcpy((*dest)->in, src->in, sizeof(*src->in));
+ }
+
+ if (src->out) {
+ if (VIR_ALLOC((*dest)->out) < 0) {
+ virReportOOMError();
+ VIR_FREE((*dest)->in);
+ goto cleanup;
+ }
+ memcpy((*dest)->out, src->out, sizeof(*src->out));
+ }
+
+ ret = 0;
+
+cleanup:
+ if (ret < 0) {
+ virNetDevBandwidthFree(*dest);
+ *dest = NULL;
+ }
+ return ret;
+}
+
+bool
+virNetDevBandwidthEqual(virNetDevBandwidthPtr a,
+ virNetDevBandwidthPtr b)
+{
+ if (!a && !b)
+ return true;
+
+ if (!a || !b)
+ return false;
+
+ /* in */
+ if (a->in->average != b->in->average ||
+ a->in->peak != b->in->peak ||
+ a->in->burst != b->in->burst)
+ return false;
+
+ /*out*/
+ if (a->out->average != b->out->average ||
+ a->out->peak != b->out->peak ||
+ a->out->burst != b->out->burst)
+ return false;
+
+ return true;
+}
diff --git a/src/util/virnetdevbandwidth.h b/src/util/virnetdevbandwidth.h
new file mode 100644
index 0000000..58decff
--- /dev/null
+++ b/src/util/virnetdevbandwidth.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2009-2011 Red Hat, 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors:
+ * Michal Privoznik <mprivozn(a)redhat.com>
+ * Daniel P. Berrange <berrange(a)redhat.com>
+ */
+
+#ifndef __VIR_NETDEV_BANDWIDTH_H__
+# define __VIR_NETDEV_BANDWIDTH_H__
+
+# include "internal.h"
+
+typedef struct _virNetDevBandwidthRate virNetDevBandwidthRate;
+typedef virNetDevBandwidthRate *virNetDevBandwidthRatePtr;
+struct _virNetDevBandwidthRate {
+ unsigned long long average; /* kbytes/s */
+ unsigned long long peak; /* kbytes/s */
+ unsigned long long burst; /* kbytes */
+};
+
+typedef struct _virNetDevBandwidth virNetDevBandwidth;
+typedef virNetDevBandwidth *virNetDevBandwidthPtr;
+struct _virNetDevBandwidth {
+ virNetDevBandwidthRatePtr in, out;
+};
+
+void virNetDevBandwidthFree(virNetDevBandwidthPtr def);
+
+int virNetDevBandwidthSet(const char *ifname, virNetDevBandwidthPtr bandwidth)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
+int virNetDevBandwidthClear(const char *ifname)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
+int virNetDevBandwidthCopy(virNetDevBandwidthPtr *dest, const virNetDevBandwidthPtr src)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
+
+bool virNetDevBandwidthEqual(virNetDevBandwidthPtr a, virNetDevBandwidthPtr b);
+
+#endif /* __VIR_NETDEV_BANDWIDTH_H__ */
diff --git a/src/util/virnetdevtap.c b/src/util/virnetdevtap.c
index 5c60925..2ed53c6 100644
--- a/src/util/virnetdevtap.c
+++ b/src/util/virnetdevtap.c
@@ -30,6 +30,7 @@
#include "virterror_internal.h"
#include "memory.h"
#include "logging.h"
+#include "util.h"
#include <sys/ioctl.h>
#ifdef HAVE_NET_IF_H
diff --git a/src/util/virnetdevvportprofile.c b/src/util/virnetdevvportprofile.c
new file mode 100644
index 0000000..29abce6
--- /dev/null
+++ b/src/util/virnetdevvportprofile.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2009-2011 Red Hat, 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors:
+ * Laine Stump <laine(a)laine.org>
+ * Daniel P. Berrange <berrange(a)redhat.com>
+ */
+
+#include <config.h>
+
+#include "virnetdevvportprofile.h"
+
+bool
+virNetDevVPortProfileEqual(virNetDevVPortProfilePtr a, virNetDevVPortProfilePtr b)
+{
+ /* NULL resistant */
+ if (!a && !b)
+ return true;
+
+ if (!a || !b)
+ return false;
+
+ if (a->virtPortType != b->virtPortType)
+ return false;
+
+ switch (a->virtPortType) {
+ case VIR_NETDEV_VPORT_PROFILE_NONE:
+ break;
+
+ case VIR_NETDEV_VPORT_PROFILE_8021QBG:
+ if (a->u.virtPort8021Qbg.managerID != b->u.virtPort8021Qbg.managerID ||
+ a->u.virtPort8021Qbg.typeID != b->u.virtPort8021Qbg.typeID ||
+ a->u.virtPort8021Qbg.typeIDVersion !=
b->u.virtPort8021Qbg.typeIDVersion ||
+ memcmp(a->u.virtPort8021Qbg.instanceID,
b->u.virtPort8021Qbg.instanceID, VIR_UUID_BUFLEN) != 0)
+ return false;
+ break;
+
+ case VIR_NETDEV_VPORT_PROFILE_8021QBH:
+ if (STRNEQ(a->u.virtPort8021Qbh.profileID,
b->u.virtPort8021Qbh.profileID))
+ return false;
+ break;
+
+ default:
+ break;
+ }
+
+ return true;
+}
diff --git a/src/util/virnetdevvportprofile.h b/src/util/virnetdevvportprofile.h
new file mode 100644
index 0000000..3e6887e
--- /dev/null
+++ b/src/util/virnetdevvportprofile.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2009-2011 Red Hat, 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors:
+ * Laine Stump <laine(a)laine.org>
+ * Daniel P. Berrange <berrange(a)redhat.com>
+ */
+
+#ifndef __VIR_NETDEV_VPORT_PROFILE_H__
+# define __VIR_NETDEV_VPORT_PROFILE_H__
+
+# include "internal.h"
+# include "uuid.h"
+# include "util.h"
+
+# define LIBVIRT_IFLA_VF_PORT_PROFILE_MAX 40
+
+enum virNetDevVPortProfile {
+ VIR_NETDEV_VPORT_PROFILE_NONE,
+ VIR_NETDEV_VPORT_PROFILE_8021QBG,
+ VIR_NETDEV_VPORT_PROFILE_8021QBH,
+
+ VIR_NETDEV_VPORT_PROFILE_LAST,
+};
+
+VIR_ENUM_DECL(virNetDevVPort)
+
+/* profile data for macvtap (VEPA) */
+typedef struct _virNetDevVPortProfile virNetDevVPortProfile;
+typedef virNetDevVPortProfile *virNetDevVPortProfilePtr;
+struct _virNetDevVPortProfile {
+ enum virNetDevVPortProfile virtPortType;
+ union {
+ struct {
+ uint8_t managerID;
+ uint32_t typeID; /* 24 bit valid */
+ uint8_t typeIDVersion;
+ unsigned char instanceID[VIR_UUID_BUFLEN];
+ } virtPort8021Qbg;
+ struct {
+ char profileID[LIBVIRT_IFLA_VF_PORT_PROFILE_MAX];
+ } virtPort8021Qbh;
+ } u;
+};
+
+
+bool virNetDevVPortProfileEqual(virNetDevVPortProfilePtr a,
+ virNetDevVPortProfilePtr b);
+
+#endif /* __VIR_NETDEV_VPORT_PROFILE_H__ */
diff --git a/src/util/virsocketaddr.c b/src/util/virsocketaddr.c
new file mode 100644
index 0000000..c2c2060
--- /dev/null
+++ b/src/util/virsocketaddr.c
@@ -0,0 +1,687 @@
+/*
+ * Copyright (C) 2009-2011 Red Hat, 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors:
+ * Daniel Veillard <veillard(a)redhat.com>
+ * Daniel P. Berrange <berrange(a)redhat.com>
+ */
+
+#include <config.h>
+
+#include "virsocketaddr.h"
+#include "virterror_internal.h"
+#include "util.h"
+
+#include <netdb.h>
+
+#define VIR_FROM_THIS VIR_FROM_NONE
+#define virSocketError(code, ...) \
+ virReportErrorHelper(VIR_FROM_THIS, code, __FILE__, \
+ __FUNCTION__, __LINE__, __VA_ARGS__)
+
+/*
+ * Helpers to extract the IP arrays from the virSocketAddrPtr
+ * That part is the less portable of the module
+ */
+typedef unsigned char virSocketAddrIPv4[4];
+typedef virSocketAddrIPv4 *virSocketAddrIPv4Ptr;
+typedef unsigned short virSocketAddrIPv6[8];
+typedef virSocketAddrIPv6 *virSocketAddrIPv6Ptr;
+
+static int virSocketAddrGetIPv4Addr(virSocketAddrPtr addr, virSocketAddrIPv4Ptr tab) {
+ unsigned long val;
+ int i;
+
+ if ((addr == NULL) || (tab == NULL) || (addr->data.stor.ss_family != AF_INET))
+ return(-1);
+
+ val = ntohl(addr->data.inet4.sin_addr.s_addr);
+
+ for (i = 0;i < 4;i++) {
+ (*tab)[3 - i] = val & 0xFF;
+ val >>= 8;
+ }
+
+ return(0);
+}
+
+static int virSocketAddrGetIPv6Addr(virSocketAddrPtr addr, virSocketAddrIPv6Ptr tab) {
+ int i;
+
+ if ((addr == NULL) || (tab == NULL) || (addr->data.stor.ss_family != AF_INET6))
+ return(-1);
+
+ for (i = 0;i < 8;i++) {
+ (*tab)[i] = ((addr->data.inet6.sin6_addr.s6_addr[2 * i] << 8) |
+ addr->data.inet6.sin6_addr.s6_addr[2 * i + 1]);
+ }
+
+ return(0);
+}
+
+/**
+ * virSocketAddrParse:
+ * @val: a numeric network address IPv4 or IPv6
+ * @addr: where to store the return value, optional.
+ * @family: address family to pass down to getaddrinfo
+ *
+ * Mostly a wrapper for getaddrinfo() extracting the address storage
+ * from the numeric string like 1.2.3.4 or 2001:db8:85a3:0:0:8a2e:370:7334
+ *
+ * Returns the length of the network address or -1 in case of error.
+ */
+int virSocketAddrParse(virSocketAddrPtr addr, const char *val, int family) {
+ int len;
+ struct addrinfo hints;
+ struct addrinfo *res = NULL;
+ int err;
+
+ if (val == NULL) {
+ virSocketError(VIR_ERR_INVALID_ARG, "%s", _("Missing
address"));
+ return -1;
+ }
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = family;
+ hints.ai_flags = AI_NUMERICHOST;
+ if ((err = getaddrinfo(val, NULL, &hints, &res)) != 0) {
+ virSocketError(VIR_ERR_SYSTEM_ERROR,
+ _("Cannot parse socket address '%s': %s"),
+ val, gai_strerror(err));
+ return -1;
+ }
+
+ if (res == NULL) {
+ virSocketError(VIR_ERR_SYSTEM_ERROR,
+ _("No socket addresses found for '%s'"),
+ val);
+ return -1;
+ }
+
+ len = res->ai_addrlen;
+ if (addr != NULL) {
+ memcpy(&addr->data.stor, res->ai_addr, len);
+ addr->len = res->ai_addrlen;
+ }
+
+ freeaddrinfo(res);
+ return(len);
+}
+
+/*
+ * virSocketAddrParseIPv4:
+ * @val: an IPv4 numeric address
+ * @addr: the location to store the result
+ *
+ * Extract the address storage from an IPv4 numeric address
+ *
+ * Returns the length of the network address or -1 in case of error.
+ */
+int
+virSocketAddrParseIPv4(virSocketAddrPtr addr, const char *val) {
+ return virSocketAddrParse(addr, val, AF_INET);
+}
+
+/*
+ * virSocketAddrParseIPv6:
+ * @val: an IPv6 numeric address
+ * @addr: the location to store the result
+ *
+ * Extract the address storage from an IPv6 numeric address
+ *
+ * Returns the length of the network address or -1 in case of error.
+ */
+int
+virSocketAddrParseIPv6(virSocketAddrPtr addr, const char *val) {
+ return virSocketAddrParse(addr, val, AF_INET6);
+}
+
+/*
+ * virSocketAddrFormat:
+ * @addr: an initialized virSocketAddrPtr
+ *
+ * Returns a string representation of the given address
+ * Returns NULL on any error
+ * Caller must free the returned string
+ */
+char *
+virSocketAddrFormat(virSocketAddrPtr addr) {
+ return virSocketAddrFormatFull(addr, false, NULL);
+}
+
+
+/*
+ * virSocketAddrFormatFull:
+ * @addr: an initialized virSocketAddrPtr
+ * @withService: if true, then service info is appended
+ * @separator: separator between hostname & service.
+ *
+ * Returns a string representation of the given address
+ * Returns NULL on any error
+ * Caller must free the returned string
+ */
+char *
+virSocketAddrFormatFull(virSocketAddrPtr addr,
+ bool withService,
+ const char *separator)
+{
+ char host[NI_MAXHOST], port[NI_MAXSERV];
+ char *addrstr;
+ int err;
+
+ if (addr == NULL) {
+ virSocketError(VIR_ERR_INVALID_ARG, "%s", _("Missing
address"));
+ return NULL;
+ }
+
+ /* Short-circuit since getnameinfo doesn't work
+ * nicely for UNIX sockets */
+ if (addr->data.sa.sa_family == AF_UNIX) {
+ if (withService) {
+ if (virAsprintf(&addrstr, "127.0.0.1%s0",
+ separator ? separator : ":") < 0)
+ goto no_memory;
+ } else {
+ if (!(addrstr = strdup("127.0.0.1")))
+ goto no_memory;
+ }
+ return addrstr;
+ }
+
+ if ((err = getnameinfo(&addr->data.sa,
+ addr->len,
+ host, sizeof(host),
+ port, sizeof(port),
+ NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
+ virSocketError(VIR_ERR_SYSTEM_ERROR,
+ _("Cannot convert socket address to string: %s"),
+ gai_strerror(err));
+ return NULL;
+ }
+
+ if (withService) {
+ if (virAsprintf(&addrstr, "%s%s%s", host, separator, port) == -1)
+ goto no_memory;
+ } else {
+ if (!(addrstr = strdup(host)))
+ goto no_memory;
+ }
+
+ return addrstr;
+
+no_memory:
+ virReportOOMError();
+ return NULL;
+}
+
+
+/*
+ * virSocketAddrSetPort:
+ * @addr: an initialized virSocketAddrPtr
+ * @port: the port number to set
+ *
+ * Set the transport layer port of the given virtSocketAddr
+ *
+ * Returns 0 on success, -1 on failure
+ */
+int
+virSocketAddrSetPort(virSocketAddrPtr addr, int port) {
+ if (addr == NULL)
+ return -1;
+
+ port = htons(port);
+
+ if(addr->data.stor.ss_family == AF_INET) {
+ addr->data.inet4.sin_port = port;
+ }
+
+ else if(addr->data.stor.ss_family == AF_INET6) {
+ addr->data.inet6.sin6_port = port;
+ }
+
+ else {
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * virSocketGetPort:
+ * @addr: an initialized virSocketAddrPtr
+ *
+ * Returns the transport layer port of the given virtSocketAddr
+ * Returns -1 if @addr is invalid
+ */
+int
+virSocketAddrGetPort(virSocketAddrPtr addr) {
+ if (addr == NULL)
+ return -1;
+
+ if(addr->data.stor.ss_family == AF_INET) {
+ return ntohs(addr->data.inet4.sin_port);
+ }
+
+ else if(addr->data.stor.ss_family == AF_INET6) {
+ return ntohs(addr->data.inet6.sin6_port);
+ }
+
+ return -1;
+}
+
+/**
+ * virSocketAddrIsNetmask:
+ * @netmask: the netmask address
+ *
+ * Check that @netmask is a proper network mask
+ *
+ * Returns 0 in case of success and -1 in case of error
+ */
+int virSocketAddrIsNetmask(virSocketAddrPtr netmask) {
+ int n = virSocketAddrGetNumNetmaskBits(netmask);
+ if (n < 0)
+ return -1;
+ return 0;
+}
+
+/**
+ * virSocketAddrMask:
+ * @addr: address that needs to be masked
+ * @netmask: the netmask address
+ * @network: where to store the result, can be same as @addr
+ *
+ * Mask off the host bits of @addr according to @netmask, turning it
+ * into a network address.
+ *
+ * Returns 0 in case of success, or -1 on error.
+ */
+int
+virSocketAddrMask(const virSocketAddrPtr addr,
+ const virSocketAddrPtr netmask,
+ virSocketAddrPtr network)
+{
+ if (addr->data.stor.ss_family != netmask->data.stor.ss_family) {
+ network->data.stor.ss_family = AF_UNSPEC;
+ return -1;
+ }
+
+ if (addr->data.stor.ss_family == AF_INET) {
+ network->data.inet4.sin_addr.s_addr
+ = (addr->data.inet4.sin_addr.s_addr
+ & netmask->data.inet4.sin_addr.s_addr);
+ network->data.inet4.sin_port = 0;
+ network->data.stor.ss_family = AF_INET;
+ network->len = addr->len;
+ return 0;
+ }
+ if (addr->data.stor.ss_family == AF_INET6) {
+ int ii;
+ for (ii = 0; ii < 16; ii++) {
+ network->data.inet6.sin6_addr.s6_addr[ii]
+ = (addr->data.inet6.sin6_addr.s6_addr[ii]
+ & netmask->data.inet6.sin6_addr.s6_addr[ii]);
+ }
+ network->data.inet6.sin6_port = 0;
+ network->data.stor.ss_family = AF_INET6;
+ network->len = addr->len;
+ return 0;
+ }
+ network->data.stor.ss_family = AF_UNSPEC;
+ return -1;
+}
+
+/**
+ * virSocketAddrMaskByPrefix:
+ * @addr: address that needs to be masked
+ * @prefix: prefix (# of 1 bits) of netmask to apply
+ * @network: where to store the result, can be same as @addr
+ *
+ * Mask off the host bits of @addr according to @prefix, turning it
+ * into a network address.
+ *
+ * Returns 0 in case of success, or -1 on error.
+ */
+int
+virSocketAddrMaskByPrefix(const virSocketAddrPtr addr,
+ unsigned int prefix,
+ virSocketAddrPtr network)
+{
+ virSocketAddr netmask;
+
+ if (virSocketAddrPrefixToNetmask(prefix, &netmask,
+ addr->data.stor.ss_family) < 0) {
+ network->data.stor.ss_family = AF_UNSPEC;
+ return -1;
+ }
+
+ return virSocketAddrMask(addr, &netmask, network);
+}
+
+/**
+ * virSocketAddrBroadcast:
+ * @addr: address that needs to be turned into broadcast address (IPv4 only)
+ * @netmask: the netmask address
+ * @broadcast: virSocketAddr to recieve the broadcast address
+ *
+ * Mask ON the host bits of @addr according to @netmask, turning it
+ * into a broadcast address.
+ *
+ * Returns 0 in case of success, or -1 on error.
+ */
+int
+virSocketAddrBroadcast(const virSocketAddrPtr addr,
+ const virSocketAddrPtr netmask,
+ virSocketAddrPtr broadcast)
+{
+ if ((addr->data.stor.ss_family != AF_INET) ||
+ (netmask->data.stor.ss_family != AF_INET)) {
+ broadcast->data.stor.ss_family = AF_UNSPEC;
+ return -1;
+ }
+
+ broadcast->data.stor.ss_family = AF_INET;
+ broadcast->len = addr->len;
+ broadcast->data.inet4.sin_addr.s_addr
+ = (addr->data.inet4.sin_addr.s_addr
+ | ~netmask->data.inet4.sin_addr.s_addr);
+ return 0;
+}
+
+/**
+ * virSocketAddrBroadcastByPrefix:
+ * @addr: address that needs to be turned into broadcast address (IPv4 only)
+ * @prefix: prefix (# of 1 bits) of netmask to apply
+ * @broadcast: virSocketAddr to recieve the broadcast address
+ *
+ * Mask off the host bits of @addr according to @prefix, turning it
+ * into a network address.
+ *
+ * Returns 0 in case of success, or -1 on error.
+ */
+int
+virSocketAddrBroadcastByPrefix(const virSocketAddrPtr addr,
+ unsigned int prefix,
+ virSocketAddrPtr broadcast)
+{
+ virSocketAddr netmask;
+
+ if (virSocketAddrPrefixToNetmask(prefix, &netmask,
+ addr->data.stor.ss_family) < 0)
+ return -1;
+
+ return virSocketAddrBroadcast(addr, &netmask, broadcast);
+}
+
+/**
+ * virSocketCheckNetmask:
+ * @addr1: a first network address
+ * @addr2: a second network address
+ * @netmask: the netmask address
+ *
+ * Check that @addr1 and @addr2 pertain to the same @netmask address
+ * range and returns the size of the range
+ *
+ * Returns 1 in case of success and 0 in case of failure and
+ * -1 in case of error
+ */
+int virSocketAddrCheckNetmask(virSocketAddrPtr addr1, virSocketAddrPtr addr2,
+ virSocketAddrPtr netmask) {
+ int i;
+
+ if ((addr1 == NULL) || (addr2 == NULL) || (netmask == NULL))
+ return(-1);
+ if ((addr1->data.stor.ss_family != addr2->data.stor.ss_family) ||
+ (addr1->data.stor.ss_family != netmask->data.stor.ss_family))
+ return(-1);
+
+ if (virSocketAddrIsNetmask(netmask) != 0)
+ return(-1);
+
+ if (addr1->data.stor.ss_family == AF_INET) {
+ virSocketAddrIPv4 t1, t2, tm;
+
+ if ((virSocketAddrGetIPv4Addr(addr1, &t1) < 0) ||
+ (virSocketAddrGetIPv4Addr(addr2, &t2) < 0) ||
+ (virSocketAddrGetIPv4Addr(netmask, &tm) < 0))
+ return(-1);
+
+ for (i = 0;i < 4;i++) {
+ if ((t1[i] & tm[i]) != (t2[i] & tm[i]))
+ return(0);
+ }
+
+ } else if (addr1->data.stor.ss_family == AF_INET6) {
+ virSocketAddrIPv6 t1, t2, tm;
+
+ if ((virSocketAddrGetIPv6Addr(addr1, &t1) < 0) ||
+ (virSocketAddrGetIPv6Addr(addr2, &t2) < 0) ||
+ (virSocketAddrGetIPv6Addr(netmask, &tm) < 0))
+ return(-1);
+
+ for (i = 0;i < 8;i++) {
+ if ((t1[i] & tm[i]) != (t2[i] & tm[i]))
+ return(0);
+ }
+
+ } else {
+ return(-1);
+ }
+ return(1);
+}
+
+/**
+ * virSocketGetRange:
+ * @start: start of an IP range
+ * @end: end of an IP range
+ *
+ * Check the order of the 2 addresses and compute the range, this
+ * will return 1 for identical addresses. Errors can come from incompatible
+ * addresses type, excessive range (>= 2^^16) where the two addresses are
+ * unrelated or inverted start and end.
+ *
+ * Returns the size of the range or -1 in case of failure
+ */
+int virSocketAddrGetRange(virSocketAddrPtr start, virSocketAddrPtr end) {
+ int ret = 0, i;
+
+ if ((start == NULL) || (end == NULL))
+ return(-1);
+ if (start->data.stor.ss_family != end->data.stor.ss_family)
+ return(-1);
+
+ if (start->data.stor.ss_family == AF_INET) {
+ virSocketAddrIPv4 t1, t2;
+
+ if ((virSocketAddrGetIPv4Addr(start, &t1) < 0) ||
+ (virSocketAddrGetIPv4Addr(end, &t2) < 0))
+ return(-1);
+
+ for (i = 0;i < 2;i++) {
+ if (t1[i] != t2[i])
+ return(-1);
+ }
+ ret = (t2[2] - t1[2]) * 256 + (t2[3] - t1[3]);
+ if (ret < 0)
+ return(-1);
+ ret++;
+ } else if (start->data.stor.ss_family == AF_INET6) {
+ virSocketAddrIPv6 t1, t2;
+
+ if ((virSocketAddrGetIPv6Addr(start, &t1) < 0) ||
+ (virSocketAddrGetIPv6Addr(end, &t2) < 0))
+ return(-1);
+
+ for (i = 0;i < 7;i++) {
+ if (t1[i] != t2[i])
+ return(-1);
+ }
+ ret = t2[7] - t1[7];
+ if (ret < 0)
+ return(-1);
+ ret++;
+ } else {
+ return(-1);
+ }
+ return(ret);
+}
+
+
+/**
+ * virSocketAddrGetNumNetmaskBits
+ * @netmask: the presumed netmask
+ *
+ * Get the number of netmask bits in a netmask.
+ *
+ * Returns the number of bits in the netmask or -1 if an error occurred
+ * or the netmask is invalid.
+ */
+int virSocketAddrGetNumNetmaskBits(const virSocketAddrPtr netmask)
+{
+ int i, j;
+ int c = 0;
+
+ if (netmask->data.stor.ss_family == AF_INET) {
+ virSocketAddrIPv4 tm;
+ uint8_t bit;
+
+ if (virSocketAddrGetIPv4Addr(netmask, &tm) < 0)
+ return -1;
+
+ for (i = 0; i < 4; i++)
+ if (tm[i] == 0xff)
+ c += 8;
+ else
+ break;
+
+ if (c == 8 * 4)
+ return c;
+
+ j = i << 3;
+ while (j < (8 * 4)) {
+ bit = 1 << (7 - (j & 7));
+ if ((tm[j >> 3] & bit)) {
+ c++;
+ } else
+ break;
+ j++;
+ }
+
+ while (j < (8 * 4)) {
+ bit = 1 << (7 - (j & 7));
+ if ((tm[j >> 3] & bit))
+ return -1;
+ j++;
+ }
+
+ return c;
+ } else if (netmask->data.stor.ss_family == AF_INET6) {
+ virSocketAddrIPv6 tm;
+ uint16_t bit;
+
+ if (virSocketAddrGetIPv6Addr(netmask, &tm) < 0)
+ return -1;
+
+ for (i = 0; i < 8; i++)
+ if (tm[i] == 0xffff)
+ c += 16;
+ else
+ break;
+
+ if (c == 16 * 8)
+ return c;
+
+ j = i << 4;
+ while (j < (16 * 8)) {
+ bit = 1 << (15 - (j & 0xf));
+ if ((tm[j >> 4] & bit)) {
+ c++;
+ } else
+ break;
+ j++;
+ }
+
+ while (j < (16 * 8)) {
+ bit = 1 << (15 - (j & 0xf));
+ if ((tm[j >> 4]) & bit)
+ return -1;
+ j++;
+ }
+
+ return c;
+ }
+ return -1;
+}
+
+/**
+ * virSocketPrefixToNetmask:
+ * @prefix: number of 1 bits to put in the netmask
+ * @netmask: address to fill in with the desired netmask
+ * @family: family of the address (AF_INET or AF_INET6 only)
+ *
+ * given @prefix and @family, fill in @netmask with a netmask
+ * (eg 255.255.255.0).
+ *
+ * Returns 0 on success or -1 on error.
+ */
+
+int
+virSocketAddrPrefixToNetmask(unsigned int prefix,
+ virSocketAddrPtr netmask,
+ int family)
+{
+ int result = -1;
+
+ netmask->data.stor.ss_family = AF_UNSPEC; /* assume failure */
+
+ if (family == AF_INET) {
+ int ip;
+
+ if (prefix > 32)
+ goto error;
+
+ ip = prefix ? ~((1 << (32 - prefix)) - 1) : 0;
+ netmask->data.inet4.sin_addr.s_addr = htonl(ip);
+ netmask->data.stor.ss_family = AF_INET;
+ result = 0;
+
+ } else if (family == AF_INET6) {
+ int ii = 0;
+
+ if (prefix > 128)
+ goto error;
+
+ while (prefix >= 8) {
+ /* do as much as possible an entire byte at a time */
+ netmask->data.inet6.sin6_addr.s6_addr[ii++] = 0xff;
+ prefix -= 8;
+ }
+ if (prefix > 0) {
+ /* final partial byte */
+ netmask->data.inet6.sin6_addr.s6_addr[ii++]
+ = ~((1 << (8 - prefix)) -1);
+ }
+ while (ii < 16) {
+ /* zerofill remainder in case it wasn't initialized */
+ netmask->data.inet6.sin6_addr.s6_addr[ii++] = 0;
+ }
+ netmask->data.stor.ss_family = AF_INET6;
+ result = 0;
+ }
+
+error:
+ return result;
+}
diff --git a/src/util/virsocketaddr.h b/src/util/virsocketaddr.h
new file mode 100644
index 0000000..24a5548
--- /dev/null
+++ b/src/util/virsocketaddr.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2009-2011 Red Hat, 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors:
+ * Daniel Veillard <veillard(a)redhat.com>
+ * Daniel P. Berrange <berrange(a)redhat.com>
+ */
+
+#ifndef __VIR_SOCKETADDR_H__
+# define __VIR_SOCKETADDR_H__
+
+# include "internal.h"
+
+# include <netinet/in.h>
+# include <sys/socket.h>
+# ifdef HAVE_SYS_UN_H
+# include <sys/un.h>
+# endif
+
+typedef struct {
+ union {
+ struct sockaddr sa;
+ struct sockaddr_storage stor;
+ struct sockaddr_in inet4;
+ struct sockaddr_in6 inet6;
+# ifdef HAVE_SYS_UN_H
+ struct sockaddr_un un;
+# endif
+ } data;
+ socklen_t len;
+} virSocketAddr;
+
+# define VIR_SOCKET_ADDR_VALID(s) \
+ ((s)->data.sa.sa_family != AF_UNSPEC)
+
+# define VIR_SOCKET_ADDR_IS_FAMILY(s, f) \
+ ((s)->data.sa.sa_family == f)
+
+# define VIR_SOCKET_ADDR_FAMILY(s) \
+ ((s)->data.sa.sa_family)
+
+typedef virSocketAddr *virSocketAddrPtr;
+
+int virSocketAddrParse(virSocketAddrPtr addr,
+ const char *val,
+ int family);
+
+int virSocketAddrParseIPv4(virSocketAddrPtr addr,
+ const char *val);
+
+int virSocketAddrParseIPv6(virSocketAddrPtr addr,
+ const char *val);
+
+char * virSocketAddrFormat(virSocketAddrPtr addr);
+char * virSocketAddrFormatFull(virSocketAddrPtr addr,
+ bool withService,
+ const char *separator);
+
+int virSocketAddrSetPort(virSocketAddrPtr addr, int port);
+
+int virSocketAddrGetPort(virSocketAddrPtr addr);
+
+int virSocketAddrGetRange(virSocketAddrPtr start,
+ virSocketAddrPtr end);
+
+int virSocketAddrIsNetmask(virSocketAddrPtr netmask);
+
+int virSocketAddrCheckNetmask(virSocketAddrPtr addr1,
+ virSocketAddrPtr addr2,
+ virSocketAddrPtr netmask);
+int virSocketAddrMask(const virSocketAddrPtr addr,
+ const virSocketAddrPtr netmask,
+ virSocketAddrPtr network);
+int virSocketAddrMaskByPrefix(const virSocketAddrPtr addr,
+ unsigned int prefix,
+ virSocketAddrPtr network);
+int virSocketAddrBroadcast(const virSocketAddrPtr addr,
+ const virSocketAddrPtr netmask,
+ virSocketAddrPtr broadcast);
+int virSocketAddrBroadcastByPrefix(const virSocketAddrPtr addr,
+ unsigned int prefix,
+ virSocketAddrPtr broadcast);
+
+int virSocketAddrGetNumNetmaskBits(const virSocketAddrPtr netmask);
+int virSocketAddrPrefixToNetmask(unsigned int prefix,
+ virSocketAddrPtr netmask,
+ int family);
+
+#endif /* __VIR_SOCKETADDR_H__ */
diff --git a/tools/virsh.c b/tools/virsh.c
index d8261f7..a479465 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -59,7 +59,7 @@
#include "threads.h"
#include "command.h"
#include "virkeycode.h"
-#include "network.h"
+#include "virnetdevbandwidth.h"
static char *progname;
--
1.7.6.4