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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list