[libvirt] [PATCH 6/9] Domain network devices can now have a <gateway> element

Cédric Bosdonnat cbosdonnat at suse.com
Fri Jul 25 15:03:29 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 7fe5976..760631d 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -3990,6 +3990,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'>
@@ -3997,6 +3998,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>
@@ -4012,6 +4014,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.8</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 74fba3d..eddac2e 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2257,6 +2257,11 @@
         </element>
       </zeroOrMore>
       <optional>
+        <element name="gateway">
+          <ref name="gateway"/>
+        </element>
+      </optional>
+      <optional>
         <element name="script">
           <attribute name="path">
             <ref name="filePath"/>
@@ -3432,6 +3437,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>
@@ -3623,6 +3641,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 8307428..607defe 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1381,6 +1381,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);
@@ -1736,6 +1739,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;
@@ -4380,6 +4385,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
@@ -4468,6 +4474,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,
@@ -6698,6 +6710,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;
@@ -6814,6 +6828,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");
@@ -7123,6 +7141,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;
@@ -7281,6 +7303,8 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
     VIR_FREE(addrtype);
     VIR_FREE(ips);
     virNWFilterHashTableFree(filterparams);
+    VIR_FREE(gateway_ipv4);
+    VIR_FREE(gateway_ipv6);
 
     return def;
 
@@ -15727,6 +15751,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)
@@ -15761,6 +15800,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;
 }
@@ -16022,6 +16063,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 8ef69b4..91cf065 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -449,6 +449,8 @@ struct _virDomainHostdevCaps {
             char *iface;
             size_t nips;
             virDomainNetIpDefPtr *ips;
+            char *gateway_ipv4;
+            char *gateway_ipv6;
         } net;
     } u;
 };
@@ -910,6 +912,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