[libvirt] [PATCHv3 07/16] Domain network devices can now have a <gateway> element

Cédric Bosdonnat cbosdonnat at suse.com
Fri Oct 10 12:03:59 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        | 23 ++++++++++++++++++++
 src/conf/domain_conf.c               | 42 ++++++++++++++++++++++++++++++++++++
 src/conf/domain_conf.h               |  4 ++++
 tests/lxcxml2xmldata/lxc-hostdev.xml |  1 +
 tests/lxcxml2xmldata/lxc-idmap.xml   |  1 +
 6 files changed, 80 insertions(+)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index e07a298..a925b6f 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -4248,6 +4248,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'>
@@ -4255,6 +4256,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>
@@ -4270,6 +4272,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 5d955b0..a7659af 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2304,6 +2304,11 @@
         </element>
       </zeroOrMore>
       <optional>
+        <element name="gateway">
+          <ref name="gateway"/>
+        </element>
+      </optional>
+      <optional>
         <element name="script">
           <attribute name="path">
             <ref name="filePath"/>
@@ -3558,6 +3563,19 @@
     </element>
   </define>
 
+  <define name="gateway">
+    <optional>
+      <attribute name="ipv4">
+        <ref name="ipv4Addr"/>
+      </attribute>
+    </optional>
+    <optional>
+      <attribute name="ipv6">
+        <ref name="ipv6Addr"/>
+      </attribute>
+    </optional>
+  </define>
+
   <define name="hostdev">
     <element name="hostdev">
       <interleave>
@@ -3788,6 +3806,11 @@
           <empty/>
         </element>
       </zeroOrMore>
+      <optional>
+        <element name="gateway">
+          <ref name="gateway"/>
+        </element>
+      </optional>
     </interleave>
   </define>
 
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index f39be87..41d5e7a 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1428,6 +1428,9 @@ void virDomainNetDefFree(virDomainNetDefPtr def)
         virDomainNetIpDefFree(def->ips[i]);
     VIR_FREE(def->ips);
 
+    VIR_FREE(def->gateway_ipv4);
+    VIR_FREE(def->gateway_ipv6);
+
     virDomainDeviceInfoClear(&def->info);
 
     VIR_FREE(def->filter);
@@ -1805,6 +1808,8 @@ void virDomainHostdevDefClear(virDomainHostdevDefPtr def)
             for (i = 0; i < def->source.caps.u.net.nips; i++)
                 virDomainNetIpDefFree(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;
@@ -4685,6 +4690,7 @@ virDomainHostdevDefParseXMLCaps(xmlNodePtr node ATTRIBUTE_UNUSED,
     xmlNodePtr sourcenode;
     xmlNodePtr *ipnodes = NULL;
     int nipnodes;
+    xmlNodePtr gwnode;
     int ret = -1;
 
     /* @type is passed in from the caller rather than read from the
@@ -4773,6 +4779,12 @@ virDomainHostdevDefParseXMLCaps(xmlNodePtr node ATTRIBUTE_UNUSED,
             }
             VIR_FREE(ipnodes);
         }
+
+        /* Look for possible gateways */
+        if ((gwnode = virXPathNode("./gateway", ctxt))) {
+            def->source.caps.u.net.gateway_ipv4 = virXMLPropString(gwnode, "ipv4");
+            def->source.caps.u.net.gateway_ipv6 = virXMLPropString(gwnode, "ipv6");
+        }
         break;
     default:
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@@ -7052,6 +7064,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;
@@ -7178,6 +7192,10 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
                         VIR_APPEND_ELEMENT(ips, nips, ip) < 0)
                         goto error;
                 }
+            } else if (!gateway_ipv4 && !gateway_ipv6 &&
+                       xmlStrEqual(cur->name, BAD_CAST "gateway")) {
+                gateway_ipv4 = virXMLPropString(cur, "ipv4");
+                gateway_ipv6 = virXMLPropString(cur, "ipv6");
             } else if (!ifname &&
                        xmlStrEqual(cur->name, BAD_CAST "target")) {
                 ifname = virXMLPropString(cur, "dev");
@@ -7496,6 +7514,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;
@@ -7761,6 +7783,8 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
     VIR_FREE(trustGuestRxFilters);
     VIR_FREE(ips);
     virNWFilterHashTableFree(filterparams);
+    VIR_FREE(gateway_ipv4);
+    VIR_FREE(gateway_ipv6);
 
     return def;
 
@@ -16763,6 +16787,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 || gateway_ipv6) {
+        virBufferAddLit(buf, "<gateway");
+        if (gateway_ipv4)
+            virBufferAsprintf(buf, " ipv4='%s'", gateway_ipv4);
+        if (gateway_ipv6)
+            virBufferAsprintf(buf, " ipv6='%s'", gateway_ipv6);
+        virBufferAddLit(buf, "/>\n");
+    }
+}
+
 static int
 virDomainHostdevDefFormatCaps(virBufferPtr buf,
                               virDomainHostdevDefPtr def)
@@ -16796,6 +16835,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;
@@ -17174,6 +17215,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 bf0e2eb..5df97c4 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -495,6 +495,8 @@ struct _virDomainHostdevCaps {
             char *iface;
             size_t nips;
             virDomainNetIpDefPtr *ips;
+            char *gateway_ipv4;
+            char *gateway_ipv6;
         } net;
     } u;
 };
@@ -988,6 +990,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 23bf04d..694bc87 100644
--- a/tests/lxcxml2xmldata/lxc-hostdev.xml
+++ b/tests/lxcxml2xmldata/lxc-hostdev.xml
@@ -37,6 +37,7 @@
       </source>
       <ip address='192.168.122.2'/>
       <ip address='2003:db8:1:0:214:1234:fe0b:3596' prefix='24'/>
+      <gateway ipv4='192.168.122.1' ipv6='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 a52da0b..80ee432 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' prefix='24'/>
       <ip address='192.168.122.13' prefix='24'/>
+      <gateway ipv4='192.168.122.1'/>
       <target dev='veth0'/>
       <guest dev='eth2'/>
     </interface>
-- 
1.8.4.5




More information about the libvir-list mailing list