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