[libvirt] [PATCH 13/33] Split src/util/network.{c, h} into 5 pieces

Daniel P. Berrange berrange at redhat.com
Thu Nov 3 17:30:09 UTC 2011


From: "Daniel P. Berrange" <berrange at 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 at redhat.com>
+ *     Daniel P. Berrange <berrange at 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 at redhat.com>
+ *     Daniel P. Berrange <berrange at 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 at laine.org>
+ *     Daniel P. Berrange <berrange at 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 at laine.org>
+ *     Daniel P. Berrange <berrange at 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 at 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 at 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 at redhat.com>
+ *     Daniel P. Berrange <berrange at 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 at redhat.com>
+ *     Daniel P. Berrange <berrange at 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 at laine.org>
+ *     Daniel P. Berrange <berrange at 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 at laine.org>
+ *     Daniel P. Berrange <berrange at 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 at redhat.com>
+ *     Daniel P. Berrange <berrange at 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 at redhat.com>
+ *     Daniel P. Berrange <berrange at 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




More information about the libvir-list mailing list