]> xenbits.xensource.com Git - libvirt.git/commitdiff
conf: single object containing list of IP addresses, list of routes
authorLaine Stump <laine@laine.org>
Mon, 6 Jun 2016 19:19:23 +0000 (15:19 -0400)
committerLaine Stump <laine@laine.org>
Sun, 26 Jun 2016 23:33:09 +0000 (19:33 -0400)
There are currently two places in the domain where this combination is
used, and there is about to be another. This patch puts them together
for brevity and uniformity.

As with the newly-renamed virNetDevIPAddr and virNetDevIPRoute
objects, the new virNetDevIPInfo object will need to be accessed by a
utility function that calls low level Netlink functions (so we don't
want it to be in the conf directory) and will be called from multiple
hypervisor drivers (so it can't be in any hypervisor directory); the
most appropriate place is thus once again the util directory.

The parse and format functions are in conf/domain_conf.c because only
the domain XML (i.e. *not* the network XML) has this exact combination
of IP addresses plus routes. Note that virDomainNetIPInfoFormat() will
end up being the only caller to virDomainNetRoutesFormat() and
virDomainNetIPsFormat(), so it will just subsume those functions in a
later patch, but we can't do that until they are no longer called.

(It would have been nice to include the interface name within the
virNetDevIPInfo object (with a slight name change), but that can't
be done cleanly, because in each case the interface name is provided
in a different place in the XML relative to the routes and IP
addresses, so putting it in this object would actually make the code
more confused rather than simpler).

docs/schemas/domaincommon.rng
src/conf/domain_conf.c
src/libvirt_private.syms
src/util/virnetdevip.c
src/util/virnetdevip.h

index b81b558d9174a22358d82b32f7700ba4314fe473..ab89dab61e597f79b51f1c735b4abfff5816a39d 100644 (file)
       </optional>
     </interleave>
   </define>
+
+  <!--
+      All ip-related info for either the host or guest side of an interface
+  -->
+  <define name="interface-ip-info">
+    <zeroOrMore>
+      <element name="ip">
+        <attribute name="address">
+          <ref name="ipAddr"/>
+        </attribute>
+        <optional>
+          <attribute name="family">
+            <ref name="addr-family"/>
+          </attribute>
+        </optional>
+        <optional>
+          <attribute name="prefix">
+            <ref name="ipPrefix"/>
+          </attribute>
+        </optional>
+        <empty/>
+      </element>
+    </zeroOrMore>
+    <zeroOrMore>
+      <ref name="route"/>
+    </zeroOrMore>
+  </define>
   <!--
       An emulator description is just a path to the binary used for the task
     -->
index 07b9a57c7e529dec8b00ec2bf945d0494609481c..def3099a99a2cf4783f9ba047a54202ef1652f6f 100644 (file)
@@ -6186,6 +6186,53 @@ virDomainNetIPParseXML(xmlNodePtr node)
     return ret;
 }
 
+
+/* fill in a virNetDevIPInfoPtr from the <route> and <ip>
+ * elements found in the given XML context.
+ *
+ * return 0 on success (including none found) and -1 on failure.
+ */
+static int ATTRIBUTE_UNUSED
+virDomainNetIPInfoParseXML(const char *source,
+                           xmlXPathContextPtr ctxt,
+                           virNetDevIPInfoPtr def)
+{
+    xmlNodePtr *nodes = NULL;
+    virNetDevIPAddrPtr ip = NULL;
+    virNetDevIPRoutePtr route = NULL;
+    int nnodes;
+    int ret = -1;
+    size_t i;
+
+    if ((nnodes = virXPathNodeSet("./ip", ctxt, &nodes)) < 0)
+        goto cleanup;
+
+    for (i = 0; i < nnodes; i++) {
+        if (!(ip = virDomainNetIPParseXML(nodes[i])) ||
+            VIR_APPEND_ELEMENT(def->ips, def->nips, ip) < 0)
+            goto cleanup;
+    }
+    VIR_FREE(nodes);
+
+    if ((nnodes = virXPathNodeSet("./route", ctxt, &nodes)) < 0)
+        goto cleanup;
+
+    for (i = 0; i < nnodes; i++) {
+        if (!(route = virNetDevIPRouteParseXML(source, nodes[i], ctxt)) ||
+            VIR_APPEND_ELEMENT(def->routes, def->nroutes, route) < 0)
+            goto cleanup;
+    }
+
+    ret = 0;
+ cleanup:
+    if (ret < 0)
+        virNetDevIPInfoClear(def);
+    VIR_FREE(ip);
+    virNetDevIPRouteFree(route);
+    VIR_FREE(nodes);
+    return ret;
+}
+
 static int
 virDomainHostdevDefParseXMLCaps(xmlNodePtr node ATTRIBUTE_UNUSED,
                                 xmlXPathContextPtr ctxt,
@@ -20322,6 +20369,19 @@ virDomainNetRoutesFormat(virBufferPtr buf,
     return 0;
 }
 
+
+static int ATTRIBUTE_UNUSED
+virDomainNetIPInfoFormat(virBufferPtr buf,
+                         virNetDevIPInfoPtr def)
+{
+    if (virDomainNetIPsFormat(buf, def->ips, def->nips) < 0)
+        return -1;
+    if (virDomainNetRoutesFormat(buf, def->routes, def->nroutes) < 0)
+        return -1;
+    return 0;
+}
+
+
 static int
 virDomainHostdevDefFormatSubsys(virBufferPtr buf,
                                 virDomainHostdevDefPtr def,
index b75db718e4086d5da5b4a1a363a8bf0897496b20..4617f5d5d2cf3d4d5635749550d03f1da4a8b2dd 100644 (file)
@@ -1931,6 +1931,7 @@ virNetDevBridgeSetVlanFiltering;
 virNetDevIPAddrAdd;
 virNetDevIPAddrDel;
 virNetDevIPAddrGet;
+virNetDevIPInfoClear;
 virNetDevIPRouteAdd;
 virNetDevIPRouteFree;
 virNetDevIPRouteGetAddress;
index 619f926782dc23ca35e1b81c02a6071434e1c2eb..376d4adbdb31e03f77d67a59a3cf8b0198e97759 100644 (file)
@@ -845,3 +845,19 @@ virNetDevIPRouteGetGateway(virNetDevIPRoutePtr def)
         return &def->gateway;
     return NULL;
 }
+
+/* manipulating the virNetDevIPInfo object */
+
+void
+virNetDevIPInfoClear(virNetDevIPInfoPtr ip)
+{
+    size_t i;
+
+    for (i = 0; i < ip->nips; i++)
+        VIR_FREE(ip->ips[i]);
+    VIR_FREE(ip->ips);
+
+    for (i = 0; i < ip->nroutes; i++)
+        virNetDevIPRouteFree(ip->routes[i]);
+    VIR_FREE(ip->routes);
+}
index 7a07b73e09a5dec9c20655c5a4b5faed0b6e7834..be41636db548c6f487975d9f11e0828d902309c6 100644 (file)
@@ -47,6 +47,14 @@ typedef struct {
     virSocketAddr gateway;      /* gateway IP address for ip-route */
 } virNetDevIPRoute, *virNetDevIPRoutePtr;
 
+/* A full set of all IP config info for a network device */
+typedef struct {
+    size_t nips;
+    virNetDevIPAddrPtr *ips;
+    size_t nroutes;
+    virNetDevIPRoutePtr *routes;
+} virNetDevIPInfo, *virNetDevIPInfoPtr;
+
 /* manipulating/querying the netdev */
 int virNetDevIPAddrAdd(const char *ifname,
                        virSocketAddr *addr,
@@ -76,4 +84,7 @@ int virNetDevIPRouteGetPrefix(virNetDevIPRoutePtr def);
 unsigned int virNetDevIPRouteGetMetric(virNetDevIPRoutePtr def);
 virSocketAddrPtr virNetDevIPRouteGetGateway(virNetDevIPRoutePtr def);
 
+/* virNetDevIPInfo object */
+void virNetDevIPInfoClear(virNetDevIPInfoPtr ip);
+
 #endif /* __VIR_NETDEVIP_H__ */