[libvirt] [PATCH v4 07/17] Domain network devices can now have a <gateway> element

Cédric Bosdonnat cbosdonnat at suse.com
Thu Nov 13 09:33:06 UTC 2014


Network interfaces devices and host devices with net capabilities can
now have an IPv4 and/or an IPv6 address configured.
---
 docs/formatdomain.html.in            |  9 +++++
 docs/schemas/domaincommon.rng        | 21 ++++++++++++
 src/conf/domain_conf.c               | 66 ++++++++++++++++++++++++++++++++++++
 src/conf/domain_conf.h               |  4 +++
 tests/lxcxml2xmldata/lxc-hostdev.xml |  2 ++
 tests/lxcxml2xmldata/lxc-idmap.xml   |  1 +
 6 files changed, 103 insertions(+)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 0984145..8500f81 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -4291,6 +4291,7 @@ qemu-kvm -net nic,model=? /dev/null
       <source network='default'/>
       <target dev='vnet0'/>
       <b><ip address='192.168.122.5' prefix='24'/></b>
+      <b><gateway ipv4='192.168.122.1'/></b>
     </interface>
     ...
     <hostdev mode='capabilities' type='net'>
@@ -4298,6 +4299,7 @@ qemu-kvm -net nic,model=? /dev/null
         <interface>eth0</interface>
       </source>
       <b><ip address='192.168.122.6' prefix='24'/></b>
+      <b><gateway ipv4='192.168.122.1'/></b>
     </hostdev>
 
   </devices>
@@ -4313,6 +4315,13 @@ qemu-kvm -net nic,model=? /dev/null
     is not mandatory since some hypervisors do not handle it.
     </p>
 
+    <p>
+    <span class="since">Since 1.2.10</span> a gateway element can also be added
+    to provide the default gateway to use for the network device. This element
+    can have either or both <code>ipv4</code> or <code>ipv6</code> attributes.
+    This is only used by the LXC driver.
+    </p>
+
     <h5><a name="elementVhostuser">vhost-user interface</a></h5>
 
     <p>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 227491f..2c6bc94 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2313,6 +2313,11 @@
           <empty/>
         </element>
       </zeroOrMore>
+      <zeroOrMore>
+        <element name="gateway">
+          <ref name="gateway"/>
+        </element>
+      </zeroOrMore>
       <optional>
         <element name="script">
           <attribute name="path">
@@ -3568,6 +3573,17 @@
     </element>
   </define>
 
+  <define name="gateway">
+    <interleave>
+      <attribute name="family">
+        <ref name="addr-family"/>
+      </attribute>
+      <attribute name="address">
+        <ref name="ipAddr"/>
+      </attribute>
+    </interleave>
+  </define>
+
   <define name="hostdev">
     <element name="hostdev">
       <interleave>
@@ -3803,6 +3819,11 @@
           <empty/>
         </element>
       </zeroOrMore>
+      <zeroOrMore>
+        <element name="gateway">
+          <ref name="gateway"/>
+        </element>
+      </zeroOrMore>
     </interleave>
   </define>
 
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 2477ebe..388a193 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1428,6 +1428,9 @@ void virDomainNetDefFree(virDomainNetDefPtr def)
         VIR_FREE(def->ips[i]);
     VIR_FREE(def->ips);
 
+    VIR_FREE(def->gateway_ipv4);
+    VIR_FREE(def->gateway_ipv6);
+
     virDomainDeviceInfoClear(&def->info);
 
     VIR_FREE(def->filter);
@@ -1800,6 +1803,8 @@ void virDomainHostdevDefClear(virDomainHostdevDefPtr def)
             for (i = 0; i < def->source.caps.u.net.nips; i++)
                 VIR_FREE(def->source.caps.u.net.ips[i]);
             VIR_FREE(def->source.caps.u.net.ips);
+            VIR_FREE(def->source.caps.u.net.gateway_ipv4);
+            VIR_FREE(def->source.caps.u.net.gateway_ipv6);
             break;
         }
         break;
@@ -4728,6 +4733,22 @@ virDomainNetIpParseXML(xmlNodePtr node)
     return NULL;
 }
 
+static void
+virDomainNetGatewayParse(xmlNodePtr node, char **ipv4, char **ipv6) {
+    char *family = virXMLPropString(node, "family");
+    if (!*ipv4 &&
+        STREQ_NULLABLE(family, "ipv4")) {
+        char *address = virXMLPropString(node, "address");
+        *ipv4 = address;
+    }
+    if (!*ipv6 &&
+        STREQ_NULLABLE(family, "ipv6")) {
+        char *address = virXMLPropString(node, "address");
+        *ipv6 = address;
+    }
+    VIR_FREE(family);
+}
+
 static int
 virDomainHostdevDefParseXMLCaps(xmlNodePtr node ATTRIBUTE_UNUSED,
                                 xmlXPathContextPtr ctxt,
@@ -4737,6 +4758,8 @@ virDomainHostdevDefParseXMLCaps(xmlNodePtr node ATTRIBUTE_UNUSED,
     xmlNodePtr sourcenode;
     xmlNodePtr *ipnodes = NULL;
     int nipnodes;
+    xmlNodePtr *gwnodes = NULL;
+    int ngwnodes;
     int ret = -1;
 
     /* @type is passed in from the caller rather than read from the
@@ -4811,6 +4834,20 @@ virDomainHostdevDefParseXMLCaps(xmlNodePtr node ATTRIBUTE_UNUSED,
                 }
             }
         }
+
+        /* Look for possible gateways */
+        if ((ngwnodes = virXPathNodeSet("./gateway", ctxt, &gwnodes)) < 0)
+            goto error;
+
+        if (ngwnodes) {
+            size_t i;
+            for (i = 0; i < ngwnodes; i++) {
+
+                virDomainNetGatewayParse(gwnodes[i],
+                                         &def->source.caps.u.net.gateway_ipv4,
+                                         &def->source.caps.u.net.gateway_ipv6);
+            }
+        }
         break;
     default:
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@@ -4821,6 +4858,7 @@ virDomainHostdevDefParseXMLCaps(xmlNodePtr node ATTRIBUTE_UNUSED,
     ret = 0;
  error:
     VIR_FREE(ipnodes);
+    VIR_FREE(gwnodes);
     return ret;
 }
 
@@ -7236,6 +7274,8 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
     size_t i;
     size_t nips = 0;
     virDomainNetIpDefPtr *ips = NULL;
+    char *gateway_ipv4 = NULL;
+    char *gateway_ipv6 = NULL;
 
     if (VIR_ALLOC(def) < 0)
         return NULL;
@@ -7332,6 +7372,8 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
 
                 if (VIR_APPEND_ELEMENT(ips, nips, ip) < 0)
                     goto error;
+            } else if (xmlStrEqual(cur->name, BAD_CAST "gateway")) {
+                virDomainNetGatewayParse(cur, &gateway_ipv4, &gateway_ipv6);
             } else if (!ifname &&
                        xmlStrEqual(cur->name, BAD_CAST "target")) {
                 ifname = virXMLPropString(cur, "dev");
@@ -7642,6 +7684,10 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
         if (VIR_APPEND_ELEMENT(def->ips, def->nips, ips[i]) < 0)
             goto error;
     }
+    def->gateway_ipv4 = gateway_ipv4;
+    gateway_ipv4 = NULL;
+    def->gateway_ipv6 = gateway_ipv6;
+    gateway_ipv6 = NULL;
 
     if (script != NULL) {
         def->script = script;
@@ -7907,6 +7953,8 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
     VIR_FREE(trustGuestRxFilters);
     VIR_FREE(ips);
     virNWFilterHashTableFree(filterparams);
+    VIR_FREE(gateway_ipv4);
+    VIR_FREE(gateway_ipv6);
 
     return def;
 
@@ -16890,6 +16938,21 @@ virDomainNetIpsFormat(virBufferPtr buf, virDomainNetIpDefPtr *ips, size_t nips)
     }
 }
 
+static void
+virDomainNetGatewayFormat(virBufferPtr buf,
+                          const char* gateway_ipv4,
+                          const char* gateway_ipv6)
+{
+    if (gateway_ipv4) {
+        virBufferAsprintf(buf, "<gateway family='ipv4' address='%s'/>\n",
+                          gateway_ipv4);
+    }
+    if (gateway_ipv6) {
+        virBufferAsprintf(buf, "<gateway family='ipv6' address='%s'/>\n",
+                          gateway_ipv6);
+    }
+}
+
 static int
 virDomainHostdevDefFormatSubsys(virBufferPtr buf,
                                 virDomainHostdevDefPtr def,
@@ -17045,6 +17108,8 @@ virDomainHostdevDefFormatCaps(virBufferPtr buf,
     if (def->source.caps.type == VIR_DOMAIN_HOSTDEV_CAPS_TYPE_NET) {
         virDomainNetIpsFormat(buf, def->source.caps.u.net.ips,
                               def->source.caps.u.net.nips);
+        virDomainNetGatewayFormat(buf, def->source.caps.u.net.gateway_ipv4,
+                                  def->source.caps.u.net.gateway_ipv6);
     }
 
     return 0;
@@ -17424,6 +17489,7 @@ virDomainNetDefFormat(virBufferPtr buf,
     }
 
     virDomainNetIpsFormat(buf, def->ips, def->nips);
+    virDomainNetGatewayFormat(buf, def->gateway_ipv4, def->gateway_ipv6);
 
     virBufferEscapeString(buf, "<script path='%s'/>\n",
                           def->script);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index bbbc8da..5678960 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -493,6 +493,8 @@ struct _virDomainHostdevCaps {
             char *iface;
             size_t nips;
             virDomainNetIpDefPtr *ips;
+            char *gateway_ipv4;
+            char *gateway_ipv6;
         } net;
     } u;
 };
@@ -993,6 +995,8 @@ struct _virDomainNetDef {
     int linkstate;
     size_t nips;
     virDomainNetIpDefPtr *ips;
+    char *gateway_ipv4;
+    char *gateway_ipv6;
 };
 
 /* Used for prefix of ifname of any network name generated dynamically
diff --git a/tests/lxcxml2xmldata/lxc-hostdev.xml b/tests/lxcxml2xmldata/lxc-hostdev.xml
index 0596789..6e4c8cf 100644
--- a/tests/lxcxml2xmldata/lxc-hostdev.xml
+++ b/tests/lxcxml2xmldata/lxc-hostdev.xml
@@ -37,6 +37,8 @@
       </source>
       <ip address='192.168.122.2' family='ipv4'/>
       <ip address='2003:db8:1:0:214:1234:fe0b:3596' family='ipv6' prefix='24'/>
+      <gateway family='ipv4' address='192.168.122.1'/>
+      <gateway family='ipv6' address='2003:db8:1:0:214:1234:fe0b:3595'/>
     </hostdev>
   </devices>
 </domain>
diff --git a/tests/lxcxml2xmldata/lxc-idmap.xml b/tests/lxcxml2xmldata/lxc-idmap.xml
index d011927..150a7d6 100644
--- a/tests/lxcxml2xmldata/lxc-idmap.xml
+++ b/tests/lxcxml2xmldata/lxc-idmap.xml
@@ -30,6 +30,7 @@
       <source bridge='bri0'/>
       <ip address='192.168.122.12' family='ipv4' prefix='24'/>
       <ip address='192.168.122.13' family='ipv4' prefix='24'/>
+      <gateway family='ipv4' address='192.168.122.1'/>
       <target dev='veth0'/>
       <guest dev='eth2'/>
     </interface>
-- 
2.1.2




More information about the libvir-list mailing list