On Thursday 13 November 2014 10:33:06 Cédric Bosdonnat wrote: > Network interfaces devices and host devices with net capabilities can > now have an IPv4 and/or an IPv6 address configured. I would rename "gateway" to "route", so it will mean an entry in a routing table. Because there will certainly be people, who would want to configure routing table more precisely than just setting default gateway. Something like <route to="10.10.0.0/16" via="10.3.0.1"> Routing table is separated from devices configuration in the kernel, and some route types don't have output device, for example blackhole. So maybe it's better to move route from interface definition to outer scope and add "dev" parameter. > --- > 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> -- Dmitry Guryanov -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list