mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-07-06 09:55:46 +00:00
network: allow limiting a <forwarder> element to certain domains
For some unknown reason the original implementation of the <forwarder> element only took advantage of part of the functionality in the dnsmasq feature it exposes - it allowed specifying the ip address of a DNS server which *all* DNS requests would be forwarded to, like this: <forwarder addr='192.168.123.25'/> This is a frontend for dnsmasq's "server" option, which also allows you to specify a domain that must be matched in order for a request to be forwarded to a particular server. This patch adds support for specifying the domain. For example: <forwarder domain='example.com' addr='192.168.1.1'/> <forwarder domain='www.example.com'/> <forwarder domain='travesty.org' addr='10.0.0.1'/> would forward requests for bob.example.com, ftp.example.com and joe.corp.example.com all to the DNS server at 192.168.1.1, but would forward requests for travesty.org and www.travesty.org to 10.0.0.1. And due to the second line, requests for www.example.com, and odd.www.example.com would be resolved by the libvirt network's own DNS server (i.e. thery wouldn't be immediately forwarded) even though they also match 'example.com' - the match is given to the entry with the longest matching domain. DNS requests not matching any of the entries would be resolved by the libvirt network's own DNS server. Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1331796
This commit is contained in:
parent
9065cfaa88
commit
0b6336c2d9
@ -847,7 +847,8 @@
|
|||||||
<dns>
|
<dns>
|
||||||
<txt name="example" value="example value" />
|
<txt name="example" value="example value" />
|
||||||
<forwarder addr="8.8.8.8"/>
|
<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'/>
|
<srv service='name' protocol='tcp' domain='test-domain-name' target='.' port='1024' priority='10' weight='10'/>
|
||||||
<host ip='192.168.122.2'>
|
<host ip='192.168.122.2'>
|
||||||
<hostname>myhost</hostname>
|
<hostname>myhost</hostname>
|
||||||
@ -915,12 +916,25 @@
|
|||||||
Currently supported sub-elements of <code><dns></code> are:
|
Currently supported sub-elements of <code><dns></code> are:
|
||||||
<dl>
|
<dl>
|
||||||
<dt><code>forwarder</code></dt>
|
<dt><code>forwarder</code></dt>
|
||||||
<dd>A <code>dns</code> element can have 0 or
|
<dd>The dns element can have 0 or
|
||||||
more <code>forwarder</code> elements. Each forwarder
|
more <code><forwarder></code> elements. Each
|
||||||
element defines an IP address to be used as forwarder in
|
forwarder element defines an alternate DNS server to use
|
||||||
DNS server configuration. The addr attribute is required
|
for some, or all, DNS requests sent to this network's DNS
|
||||||
and defines the IP address of every
|
server. There are two attributes - <code>domain</code>,
|
||||||
forwarder. <span class="since">Since 1.1.3</span>
|
and <code>addr</code>; at least one of these must be
|
||||||
|
specified in any <code><forwarder></code>
|
||||||
|
element. If both <code>domain</code> and <code>addr</code>
|
||||||
|
are specified, then all requests that match the given
|
||||||
|
domain will be forwarded to the DNS server at addr. If
|
||||||
|
only <code>domain</code> 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 <code>addr</code> 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. <code>addr</code> <span class="since">Since
|
||||||
|
1.1.3</span>, <code>domain</code> <span class="since">Since
|
||||||
|
2.2.0</span>.
|
||||||
</dd>
|
</dd>
|
||||||
<dt><code>txt</code></dt>
|
<dt><code>txt</code></dt>
|
||||||
<dd>A <code>dns</code> element can have 0 or more <code>txt</code> elements.
|
<dd>A <code>dns</code> element can have 0 or more <code>txt</code> elements.
|
||||||
|
@ -260,7 +260,13 @@
|
|||||||
<interleave>
|
<interleave>
|
||||||
<zeroOrMore>
|
<zeroOrMore>
|
||||||
<element name="forwarder">
|
<element name="forwarder">
|
||||||
<attribute name="addr"><ref name="ipAddr"/></attribute>
|
<optional>
|
||||||
|
<attribute name="addr"><ref name="ipAddr"/></attribute>
|
||||||
|
</optional>
|
||||||
|
<optional>
|
||||||
|
<attribute name="domain"><ref name="dnsName"/></attribute>
|
||||||
|
</optional>
|
||||||
|
<empty/>
|
||||||
</element>
|
</element>
|
||||||
</zeroOrMore>
|
</zeroOrMore>
|
||||||
<zeroOrMore>
|
<zeroOrMore>
|
||||||
|
@ -349,12 +349,20 @@ virNetworkDNSSrvDefClear(virNetworkDNSSrvDefPtr def)
|
|||||||
VIR_FREE(def->target);
|
VIR_FREE(def->target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
virNetworkDNSForwarderClear(virNetworkDNSForwarderPtr def)
|
||||||
|
{
|
||||||
|
VIR_FREE(def->domain);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
virNetworkDNSDefClear(virNetworkDNSDefPtr def)
|
virNetworkDNSDefClear(virNetworkDNSDefPtr def)
|
||||||
{
|
{
|
||||||
if (def->forwarders) {
|
if (def->forwarders) {
|
||||||
while (def->nfwds)
|
while (def->nfwds)
|
||||||
VIR_FREE(def->forwarders[--def->nfwds]);
|
virNetworkDNSForwarderClear(&def->forwarders[--def->nfwds]);
|
||||||
VIR_FREE(def->forwarders);
|
VIR_FREE(def->forwarders);
|
||||||
}
|
}
|
||||||
if (def->txts) {
|
if (def->txts) {
|
||||||
@ -1379,14 +1387,25 @@ virNetworkDNSDefParseXML(const char *networkName,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
for (i = 0; i < nfwds; i++) {
|
for (i = 0; i < nfwds; i++) {
|
||||||
def->forwarders[i] = virXMLPropString(fwdNodes[i], "addr");
|
char *addr = virXMLPropString(fwdNodes[i], "addr");
|
||||||
if (virSocketAddrParse(NULL, def->forwarders[i], AF_UNSPEC) < 0) {
|
|
||||||
|
if (addr && virSocketAddrParse(&def->forwarders[i].addr,
|
||||||
|
addr, AF_UNSPEC) < 0) {
|
||||||
virReportError(VIR_ERR_XML_ERROR,
|
virReportError(VIR_ERR_XML_ERROR,
|
||||||
_("Invalid forwarder IP address '%s' "
|
_("Invalid forwarder IP address '%s' "
|
||||||
"in network '%s'"),
|
"in network '%s'"),
|
||||||
def->forwarders[i], networkName);
|
addr, networkName);
|
||||||
|
VIR_FREE(addr);
|
||||||
goto cleanup;
|
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++;
|
def->nfwds++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2554,8 +2573,22 @@ virNetworkDNSDefFormat(virBufferPtr buf,
|
|||||||
virBufferAdjustIndent(buf, 2);
|
virBufferAdjustIndent(buf, 2);
|
||||||
|
|
||||||
for (i = 0; i < def->nfwds; i++) {
|
for (i = 0; i < def->nfwds; i++) {
|
||||||
virBufferAsprintf(buf, "<forwarder addr='%s'/>\n",
|
|
||||||
def->forwarders[i]);
|
virBufferAddLit(buf, "<forwarder");
|
||||||
|
if (def->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++) {
|
for (i = 0; i < def->ntxts; i++) {
|
||||||
|
@ -125,6 +125,12 @@ struct _virNetworkDNSHostDef {
|
|||||||
char **names;
|
char **names;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _virNetworkDNSForwarder {
|
||||||
|
virSocketAddr addr;
|
||||||
|
char *domain;
|
||||||
|
} virNetworkDNSForwarder, *virNetworkDNSForwarderPtr;
|
||||||
|
|
||||||
typedef struct _virNetworkDNSDef virNetworkDNSDef;
|
typedef struct _virNetworkDNSDef virNetworkDNSDef;
|
||||||
typedef virNetworkDNSDef *virNetworkDNSDefPtr;
|
typedef virNetworkDNSDef *virNetworkDNSDefPtr;
|
||||||
struct _virNetworkDNSDef {
|
struct _virNetworkDNSDef {
|
||||||
@ -137,7 +143,7 @@ struct _virNetworkDNSDef {
|
|||||||
size_t nsrvs;
|
size_t nsrvs;
|
||||||
virNetworkDNSSrvDefPtr srvs;
|
virNetworkDNSSrvDefPtr srvs;
|
||||||
size_t nfwds;
|
size_t nfwds;
|
||||||
char **forwarders;
|
virNetworkDNSForwarderPtr forwarders;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _virNetworkIPDef virNetworkIPDef;
|
typedef struct _virNetworkIPDef virNetworkIPDef;
|
||||||
|
@ -958,8 +958,21 @@ networkDnsmasqConfContents(virNetworkObjPtr network,
|
|||||||
if (wantDNS && network->def->dns.forwarders) {
|
if (wantDNS && network->def->dns.forwarders) {
|
||||||
virBufferAddLit(&configbuf, "no-resolv\n");
|
virBufferAddLit(&configbuf, "no-resolv\n");
|
||||||
for (i = 0; i < network->def->dns.nfwds; i++) {
|
for (i = 0; i < network->def->dns.nfwds; i++) {
|
||||||
virBufferAsprintf(&configbuf, "server=%s\n",
|
virNetworkDNSForwarderPtr fwd = &network->def->dns.forwarders[i];
|
||||||
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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,8 @@ strict-order
|
|||||||
no-resolv
|
no-resolv
|
||||||
server=8.8.8.8
|
server=8.8.8.8
|
||||||
server=8.8.4.4
|
server=8.8.4.4
|
||||||
|
server=/example.com/192.168.1.1
|
||||||
|
server=/www.example.com/#
|
||||||
except-interface=lo
|
except-interface=lo
|
||||||
bind-dynamic
|
bind-dynamic
|
||||||
interface=virbr0
|
interface=virbr0
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
<dns>
|
<dns>
|
||||||
<forwarder addr='8.8.8.8'/>
|
<forwarder addr='8.8.8.8'/>
|
||||||
<forwarder addr='8.8.4.4'/>
|
<forwarder addr='8.8.4.4'/>
|
||||||
|
<forwarder domain='example.com' addr='192.168.1.1'/>
|
||||||
|
<forwarder domain='www.example.com'/>
|
||||||
</dns>
|
</dns>
|
||||||
<ip address='192.168.122.1' netmask='255.255.255.0'>
|
<ip address='192.168.122.1' netmask='255.255.255.0'>
|
||||||
</ip>
|
</ip>
|
||||||
|
@ -4,8 +4,10 @@
|
|||||||
<forward dev='eth0' mode='nat'/>
|
<forward dev='eth0' mode='nat'/>
|
||||||
<bridge name='virbr0' stp='on' delay='0' />
|
<bridge name='virbr0' stp='on' delay='0' />
|
||||||
<dns>
|
<dns>
|
||||||
<forwarder addr='8.8.8.8' />
|
<forwarder addr='8.8.8.8'/>
|
||||||
<forwarder addr='8.8.4.4' />
|
<forwarder addr='8.8.4.4'/>
|
||||||
|
<forwarder domain='example.com' addr='192.168.1.1'/>
|
||||||
|
<forwarder domain='www.example.com'/>
|
||||||
</dns>
|
</dns>
|
||||||
<ip address='192.168.122.1' netmask='255.255.255.0'>
|
<ip address='192.168.122.1' netmask='255.255.255.0'>
|
||||||
</ip>
|
</ip>
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
<dns>
|
<dns>
|
||||||
<forwarder addr='8.8.8.8'/>
|
<forwarder addr='8.8.8.8'/>
|
||||||
<forwarder addr='8.8.4.4'/>
|
<forwarder addr='8.8.4.4'/>
|
||||||
|
<forwarder domain='example.com' addr='192.168.1.1'/>
|
||||||
|
<forwarder domain='www.example.com'/>
|
||||||
</dns>
|
</dns>
|
||||||
<ip address='192.168.122.1' netmask='255.255.255.0'>
|
<ip address='192.168.122.1' netmask='255.255.255.0'>
|
||||||
</ip>
|
</ip>
|
||||||
|
Loading…
Reference in New Issue
Block a user