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 d0141f8..7eaf026 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -4080,6 +4080,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'>
@@ -4087,6 +4088,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>
@@ -4102,6 +4104,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 0c8846d..8b89922 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2280,6 +2280,11 @@
</element>
</zeroOrMore>
<optional>
+ <element name="gateway">
+ <ref name="gateway"/>
+ </element>
+ </optional>
+ <optional>
<element name="script">
<attribute name="path">
<ref name="filePath"/>
@@ -3463,6 +3468,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>
@@ -3693,6 +3711,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 8a24868..e1070a6 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1399,6 +1399,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);
@@ -1765,6 +1768,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;
@@ -4591,6 +4596,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
@@ -4679,6 +4685,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,
@@ -6917,6 +6929,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;
@@ -7033,6 +7047,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");
@@ -7342,6 +7360,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;
@@ -7500,6 +7522,8 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
VIR_FREE(addrtype);
VIR_FREE(ips);
virNWFilterHashTableFree(filterparams);
+ VIR_FREE(gateway_ipv4);
+ VIR_FREE(gateway_ipv6);
return def;
@@ -16135,6 +16159,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)
@@ -16169,6 +16208,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;
@@ -16431,6 +16472,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 5c1ecb7..3ddca8c 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -489,6 +489,8 @@ struct _virDomainHostdevCaps {
char *iface;
size_t nips;
virDomainNetIpDefPtr *ips;
+ char *gateway_ipv4;
+ char *gateway_ipv6;
} net;
} u;
};
@@ -961,6 +963,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