diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in index e103dd7857..13ca32de97 100644 --- a/docs/formatnetwork.html.in +++ b/docs/formatnetwork.html.in @@ -847,7 +847,8 @@ <dns> <txt name="example" value="example value" /> <forwarder addr="8.8.8.8"/> - <forwarder addr="8.8.4.4"/> + <forwarder domain='example.com' addr="8.8.4.4"/> + <forwarder domain='www.example.com'/> <srv service='name' protocol='tcp' domain='test-domain-name' target='.' port='1024' priority='10' weight='10'/> <host ip='192.168.122.2'> <hostname>myhost</hostname> @@ -915,12 +916,25 @@ Currently supported sub-elements of <dns> are:
forwarder
-
A dns element can have 0 or - more forwarder elements. Each forwarder - element defines an IP address to be used as forwarder in - DNS server configuration. The addr attribute is required - and defines the IP address of every - forwarder. Since 1.1.3 +
The dns element can have 0 or + more <forwarder> elements. Each + forwarder element defines an alternate DNS server to use + for some, or all, DNS requests sent to this network's DNS + server. There are two attributes - domain, + and addr; at least one of these must be + specified in any <forwarder> + element. If both domain and addr + are specified, then all requests that match the given + domain will be forwarded to the DNS server at addr. If + only domain is specified, then all matching + domains will be resolved locally (or via the host's + standard DNS forwarding if they can't be resolved + locally). If an addr is specified by itself, + then all DNS requests to the network's DNS server will be + forwarded to the DNS server at that address with no + exceptions. addr Since + 1.1.3, domain Since + 2.2.0.
txt
A dns element can have 0 or more txt elements. diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng index 12d4b34505..1a18e64b24 100644 --- a/docs/schemas/network.rng +++ b/docs/schemas/network.rng @@ -260,7 +260,13 @@ - + + + + + + + diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index d77b8379fe..aa397768c9 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -349,12 +349,20 @@ virNetworkDNSSrvDefClear(virNetworkDNSSrvDefPtr def) VIR_FREE(def->target); } + +static void +virNetworkDNSForwarderClear(virNetworkDNSForwarderPtr def) +{ + VIR_FREE(def->domain); +} + + static void virNetworkDNSDefClear(virNetworkDNSDefPtr def) { if (def->forwarders) { while (def->nfwds) - VIR_FREE(def->forwarders[--def->nfwds]); + virNetworkDNSForwarderClear(&def->forwarders[--def->nfwds]); VIR_FREE(def->forwarders); } if (def->txts) { @@ -1379,14 +1387,25 @@ virNetworkDNSDefParseXML(const char *networkName, goto cleanup; for (i = 0; i < nfwds; i++) { - def->forwarders[i] = virXMLPropString(fwdNodes[i], "addr"); - if (virSocketAddrParse(NULL, def->forwarders[i], AF_UNSPEC) < 0) { + char *addr = virXMLPropString(fwdNodes[i], "addr"); + + if (addr && virSocketAddrParse(&def->forwarders[i].addr, + addr, AF_UNSPEC) < 0) { virReportError(VIR_ERR_XML_ERROR, - _("Invalid forwarder IP address '%s' " - "in network '%s'"), - def->forwarders[i], networkName); + _("Invalid forwarder IP address '%s' " + "in network '%s'"), + addr, networkName); + VIR_FREE(addr); goto cleanup; } + def->forwarders[i].domain = virXMLPropString(fwdNodes[i], "domain"); + if (!(addr || def->forwarders[i].domain)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Invalid forwarder element, must contain " + "at least one of addr or domain")); + goto cleanup; + } + VIR_FREE(addr); def->nfwds++; } } @@ -2554,8 +2573,22 @@ virNetworkDNSDefFormat(virBufferPtr buf, virBufferAdjustIndent(buf, 2); for (i = 0; i < def->nfwds; i++) { - virBufferAsprintf(buf, "\n", - def->forwarders[i]); + + virBufferAddLit(buf, "forwarders[i].domain) { + virBufferEscapeString(buf, " domain='%s'", + def->forwarders[i].domain); + } + if (VIR_SOCKET_ADDR_VALID(&def->forwarders[i].addr)) { + char *addr = virSocketAddrFormat(&def->forwarders[i].addr); + + if (!addr) + return -1; + + virBufferAsprintf(buf, " addr='%s'", addr); + VIR_FREE(addr); + } + virBufferAddLit(buf, "/>\n"); } for (i = 0; i < def->ntxts; i++) { diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h index 9ebd4a73eb..3b227db6f3 100644 --- a/src/conf/network_conf.h +++ b/src/conf/network_conf.h @@ -125,6 +125,12 @@ struct _virNetworkDNSHostDef { char **names; }; + +typedef struct _virNetworkDNSForwarder { + virSocketAddr addr; + char *domain; +} virNetworkDNSForwarder, *virNetworkDNSForwarderPtr; + typedef struct _virNetworkDNSDef virNetworkDNSDef; typedef virNetworkDNSDef *virNetworkDNSDefPtr; struct _virNetworkDNSDef { @@ -137,7 +143,7 @@ struct _virNetworkDNSDef { size_t nsrvs; virNetworkDNSSrvDefPtr srvs; size_t nfwds; - char **forwarders; + virNetworkDNSForwarderPtr forwarders; }; typedef struct _virNetworkIPDef virNetworkIPDef; diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 49c0a2fa76..74f75d015f 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -958,8 +958,21 @@ networkDnsmasqConfContents(virNetworkObjPtr network, if (wantDNS && network->def->dns.forwarders) { virBufferAddLit(&configbuf, "no-resolv\n"); for (i = 0; i < network->def->dns.nfwds; i++) { - virBufferAsprintf(&configbuf, "server=%s\n", - network->def->dns.forwarders[i]); + virNetworkDNSForwarderPtr fwd = &network->def->dns.forwarders[i]; + + virBufferAddLit(&configbuf, "server="); + if (fwd->domain) + virBufferAsprintf(&configbuf, "/%s/", fwd->domain); + if (VIR_SOCKET_ADDR_VALID(&fwd->addr)) { + char *addr = virSocketAddrFormat(&fwd->addr); + + if (!addr) + goto cleanup; + virBufferAsprintf(&configbuf, "%s\n", addr); + } else { + /* "don't forward requests for this domain" */ + virBufferAddLit(&configbuf, "#\n"); + } } } diff --git a/tests/networkxml2confdata/nat-network-dns-forwarders.conf b/tests/networkxml2confdata/nat-network-dns-forwarders.conf index 8bf3b9c360..0bd76bf60c 100644 --- a/tests/networkxml2confdata/nat-network-dns-forwarders.conf +++ b/tests/networkxml2confdata/nat-network-dns-forwarders.conf @@ -8,6 +8,8 @@ strict-order no-resolv server=8.8.8.8 server=8.8.4.4 +server=/example.com/192.168.1.1 +server=/www.example.com/# except-interface=lo bind-dynamic interface=virbr0 diff --git a/tests/networkxml2confdata/nat-network-dns-forwarders.xml b/tests/networkxml2confdata/nat-network-dns-forwarders.xml index 8fab78ea3a..5d4f3fa697 100644 --- a/tests/networkxml2confdata/nat-network-dns-forwarders.xml +++ b/tests/networkxml2confdata/nat-network-dns-forwarders.xml @@ -6,6 +6,8 @@ + + diff --git a/tests/networkxml2xmlin/nat-network-dns-forwarders.xml b/tests/networkxml2xmlin/nat-network-dns-forwarders.xml index 4d7310d1c6..426dd45cd9 100644 --- a/tests/networkxml2xmlin/nat-network-dns-forwarders.xml +++ b/tests/networkxml2xmlin/nat-network-dns-forwarders.xml @@ -4,8 +4,10 @@ - - + + + + diff --git a/tests/networkxml2xmlout/nat-network-dns-forwarders.xml b/tests/networkxml2xmlout/nat-network-dns-forwarders.xml index 930a42abc0..c05ad5514d 100644 --- a/tests/networkxml2xmlout/nat-network-dns-forwarders.xml +++ b/tests/networkxml2xmlout/nat-network-dns-forwarders.xml @@ -8,6 +8,8 @@ + +