On 12/01/2014 03:40 AM, John Ferlan wrote:
On 11/20/2014 09:46 PM, Josh Stone wrote:
> This adds a new "localOnly" attribute on the domain element of the
> network xml. With this set to "yes", DNS requests under that domain
> will only be resolved by libvirt's dnsmasq, never forwarded upstream.
>
> This was how it worked before commit f69a6b987d616, and I found that
> functionality useful. For example, I have my host's NetworkManager
> dnsmasq configured to forward that domain to libvirt's dnsmasq, so I can
> easily resolve guest names from outside. But if libvirt's dnsmasq
> doesn't know a name and forwards it to the host, I'd get an endless
> forwarding loop. Now I can set localOnly="yes" to prevent the loop.
>
> Signed-off-by: Josh Stone <jistone(a)redhat.com>
> Cc: Laine Stump <laine(a)laine.org>
Depending on how you proceed with Martin's comments...
> ---
> docs/formatnetwork.html.in | 12 +++++++++++-
> docs/schemas/network.rng | 3 +++
> src/conf/network_conf.c | 5 +++++
> src/conf/network_conf.h | 1 +
> src/network/bridge_driver.c | 5 +++++
> .../networkxml2confdata/nat-network-dns-local-domain.conf | 14 ++++++++++++++
> tests/networkxml2confdata/nat-network-dns-local-domain.xml | 9 +++++++++
> tests/networkxml2conftest.c | 1 +
> 8 files changed, 49 insertions(+), 1 deletion(-)
> create mode 100644 tests/networkxml2confdata/nat-network-dns-local-domain.conf
> create mode 100644 tests/networkxml2confdata/nat-network-dns-local-domain.xml
>
> diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in
> index dc438aee8622..defcdba00930 100644
> --- a/docs/formatnetwork.html.in
> +++ b/docs/formatnetwork.html.in
> @@ -82,7 +82,7 @@
> <pre>
> ...
> <bridge name="virbr0" stp="on"
delay="5"/>
> - <domain name="example.com"/>
> + <domain name="example.com"
localOnly="no"/>
> <forward mode="nat" dev="eth0"/>
> ...</pre>
>
> @@ -113,6 +113,16 @@
> a <code><forward></code> mode of "nat"
or "route" (or an
> isolated network with no <code><forward></code>
> element). <span class="since">Since 0.4.5</span>
> +
> + <p>
> + If the optional <code>localOnly</code> attribute on the
> + <code>domain</code> element is "yes", then DNS
requests under
> + this domain will only be resolved by the virtual network's own
> + DNS server - they will not be forwarded to the host's upstream
> + DNS server. If <code>localOnly</code> is "no", and
by
> + default, unresolved requests <b>will</b> be forwarded.
> + <span class="since">Since 1.2.11</span>
> + </p>
> </dd>
> <dt><code>forward</code></dt>
> <dd>Inclusion of the <code>forward</code> element indicates
that
> diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
> index 4546f8037580..a1da28092375 100644
> --- a/docs/schemas/network.rng
> +++ b/docs/schemas/network.rng
> @@ -225,6 +225,9 @@
> <optional>
> <element name="domain">
> <attribute name="name"><ref
name="dnsName"/></attribute>
> + <optional>
> + <attribute name="localOnly"><ref
name="virYesNo"/></attribute>
> + </optional>
> </element>
> </optional>
>
> diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
> index 067334e87cb0..61451c39805f 100644
> --- a/src/conf/network_conf.c
> +++ b/src/conf/network_conf.c
> @@ -2083,6 +2083,11 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
>
> /* Parse network domain information */
> def->domain = virXPathString("string(./domain[1]/@name)", ctxt);
> + tmp = virXPathString("string(./domain[1]/@localOnly)", ctxt);
> + if (tmp) {
> + def->domain_local = STRCASEEQ(tmp, "yes");
> + VIR_FREE(tmp);
> + }
This should use virTristateBoolTypeFromString like other yes/no processing.
Ok, I just didn't see any really consistent way to parse these.
STRCASEEQ was just simple and also used elsewhere, for @default and
@managed, but maybe those aren't tristate.
Also how do you save in the XML what you've read in (hint:
Format*
function)? Perhaps look at 'forwardPlainNames' for an example of
Tristate and find all the places it touches. Something is a Tristate
when it's optional, can be yes or no, and has a default...
Ah, I missed Format, thanks. I'll update with forwardPlainNames as a
template, if the other subthread concludes localOnly is still useful.
> if ((bandwidthNode = virXPathNode("./bandwidth",
ctxt)) != NULL &&
> (def->bandwidth = virNetDevBandwidthParse(bandwidthNode, -1)) == NULL)
> diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
> index 660cd2d10cd1..6308a7dcfbf7 100644
> --- a/src/conf/network_conf.h
> +++ b/src/conf/network_conf.h
> @@ -232,6 +232,7 @@ struct _virNetworkDef {
>
> char *bridge; /* Name of bridge device */
> char *domain;
> + bool domain_local; /* Choose not to forward dns for this domain */
This would then be:
int domain_local; /* enum virTristateBool */
> unsigned long delay; /* Bridge forward delay (ms) */
> bool stp; /* Spanning tree protocol */
> virMacAddr mac; /* mac address of bridge device */
> diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
> index 6cb421c52850..dfa375d3aa72 100644
> --- a/src/network/bridge_driver.c
> +++ b/src/network/bridge_driver.c
> @@ -912,6 +912,11 @@ networkDnsmasqConfContents(virNetworkObjPtr network,
> }
>
> if (network->def->domain) {
> + if (network->def->domain_local) {
This would then check using == VIR_TRISTATE_BOOL_YES
> + virBufferAsprintf(&configbuf,
> + "local=/%s/\n",
> + network->def->domain);
> + }
> virBufferAsprintf(&configbuf,
> "domain=%s\n"
> "expand-hosts\n",
> diff --git a/tests/networkxml2confdata/nat-network-dns-local-domain.conf
b/tests/networkxml2confdata/nat-network-dns-local-domain.conf
> new file mode 100644
> index 000000000000..5f41b9186cbc
> --- /dev/null
> +++ b/tests/networkxml2confdata/nat-network-dns-local-domain.conf
> @@ -0,0 +1,14 @@
> +##WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
> +##OVERWRITTEN AND LOST. Changes to this configuration should be made using:
> +## virsh net-edit default
> +## or other application using the libvirt API.
> +##
> +## dnsmasq conf file created by libvirt
> +strict-order
> +local=/example.com/
> +domain=example.com
> +expand-hosts
> +except-interface=lo
> +bind-dynamic
> +interface=virbr0
> +addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts
> diff --git a/tests/networkxml2confdata/nat-network-dns-local-domain.xml
b/tests/networkxml2confdata/nat-network-dns-local-domain.xml
> new file mode 100644
> index 000000000000..a92d71f1f2f6
> --- /dev/null
> +++ b/tests/networkxml2confdata/nat-network-dns-local-domain.xml
> @@ -0,0 +1,9 @@
> +<network>
> + <name>default</name>
> + <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9c</uuid>
> + <forward dev='eth0' mode='nat'/>
> + <bridge name='virbr0' stp='on' delay='0' />
> + <domain name='example.com' localOnly='yes'/>
> + <ip address='192.168.122.1' netmask='255.255.255.0'>
> + </ip>
> +</network>
> diff --git a/tests/networkxml2conftest.c b/tests/networkxml2conftest.c
> index 4f1d9345ffe4..d2aa8c62cfcd 100644
> --- a/tests/networkxml2conftest.c
> +++ b/tests/networkxml2conftest.c
> @@ -146,6 +146,7 @@ mymain(void)
> DO_TEST("nat-network-dns-hosts", full);
> DO_TEST("nat-network-dns-forward-plain", full);
> DO_TEST("nat-network-dns-forwarders", full);
> + DO_TEST("nat-network-dns-local-domain", full);
> DO_TEST("dhcp6-network", dhcpv6);
> DO_TEST("dhcp6-nat-network", dhcpv6);
> DO_TEST("dhcp6host-routed-network", dhcpv6);
>