Support for optional parameters <ipv[46]routing> in XML network definition.
These parameters allows to set up alternative binary or script to be run
during network start. Such customization allows to run additional services
for started network (besides default DHCP/DNS/NDP) or modify/pass additional
options to dnsmasq and/or radvd.
If <ipv[46]routing> parameters point to default /usr/sbin/dnsmasq or
/usr/sbin/radvd
they are removed from XML network definition.
---
docs/schemas/network.rng | 28 +++++++++++++++
src/conf/network_conf.c | 37 ++++++++++++++++++++
src/conf/network_conf.h | 5 +++
src/network/bridge_driver.c | 8 ++--
.../networkxml2xmlin/with-ipv4routing-network.xml | 11 ++++++
.../networkxml2xmlout/with-ipv4routing-network.xml | 11 ++++++
tests/networkxml2xmltest.c | 1 +
7 files changed, 97 insertions(+), 4 deletions(-)
diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
index 4252f30..71234a3 100644
--- a/docs/schemas/network.rng
+++ b/docs/schemas/network.rng
@@ -21,6 +21,16 @@
<element name="uuid"><text/></element>
</optional>
+ <!-- <ipv4routing> element -->
+ <optional>
+ <ref name="ipv4routing"/>
+ </optional>
+
+ <!-- <ipv6routing> element -->
+ <optional>
+ <ref name="ipv6routing"/>
+ </optional>
+
<!-- <bridge> element -->
<optional>
<!-- The name of the network to be set up; this will back
@@ -175,4 +185,22 @@
</data>
</define>
+ <!-- ipv4routing and ipv6routing description is a path to the binary -->
+ <define name="ipv4routing">
+ <element name="ipv4routing">
+ <ref name="absFilePath"/>
+ </element>
+ </define>
+
+ <define name="ipv6routing">
+ <element name="ipv6routing">
+ <ref name="absFilePath"/>
+ </element>
+ </define>
+
+ <define name="absFilePath">
+ <data type="string">
+ <param
name="pattern">/[a-zA-Z0-9_\.\+\-\\&"'<>/%]+</param>
+ </data>
+ </define>
</grammar>
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 420b94a..b70397f 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -115,6 +115,8 @@ void virNetworkDefFree(virNetworkDefPtr def)
VIR_FREE(def->bridge);
VIR_FREE(def->forwardDev);
VIR_FREE(def->domain);
+ VIR_FREE(def->ipv4routing);
+ VIR_FREE(def->ipv6routing);
for (ii = 0 ; ii < def->nips && def->ips ; ii++) {
virNetworkIpDefClear(&def->ips[ii]);
@@ -612,6 +614,36 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
VIR_FREE(tmp);
}
+ /* Extract path to ipv4routing binary */
+ def->ipv4routing = virXPathString("string(./ipv4routing[1])", ctxt);
+ if (def->ipv4routing) {
+ if (access(def->ipv4routing, X_OK) < 0) {
+ virNetworkReportError(VIR_ERR_INTERNAL_ERROR, _("Cannot
find IPv4Routing binary %s"), def->ipv4routing);
+ goto error;
+ }
+ } else {
+ def->ipv4routing = strdup(DNSMASQ);
+ if (!def->ipv4routing) {
+ virReportOOMError();
+ goto error;
+ }
+ }
+
+ /* Extract path to ipv6routing binary */
+ def->ipv6routing = virXPathString("string(./ipv6routing[1])", ctxt);
+ if (def->ipv6routing) {
+ if (access(def->ipv6routing, X_OK) < 0) {
+ virNetworkReportError(VIR_ERR_INTERNAL_ERROR, _("Cannot
find IPv6Routing binary %s"), def->ipv6routing);
+ goto error;
+ }
+ } else {
+ def->ipv6routing = strdup(RADVD);
+ if (!def->ipv6routing) {
+ virReportOOMError();
+ goto error;
+ }
+ }
+
/* Parse network domain information */
def->domain = virXPathString("string(./domain[1]/@name)", ctxt);
@@ -831,6 +863,11 @@ char *virNetworkDefFormat(const virNetworkDefPtr def)
virUUIDFormat(uuid, uuidstr);
virBufferVSprintf(&buf, " <uuid>%s</uuid>\n", uuidstr);
+ if (def->ipv4routing && STRNEQ(def->ipv4routing, DNSMASQ))
+ virBufferEscapeString(&buf, "
<ipv4routing>%s</ipv4routing>\n", def->ipv4routing);
+ if (def->ipv6routing && STRNEQ(def->ipv6routing, RADVD))
+ virBufferEscapeString(&buf, "
<ipv6routing>%s</ipv6routing>\n", def->ipv6routing);
+
if (def->forwardType != VIR_NETWORK_FORWARD_NONE) {
const char *mode = virNetworkForwardTypeToString(def->forwardType);
if (mode) {
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index fd96c36..8df600c 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -98,6 +98,11 @@ struct _virNetworkDef {
size_t nips;
virNetworkIpDefPtr ips; /* ptr to array of IP addresses on this network */
+
+ char *ipv4routing; /* path to binary for configuring IPv4
network (DNS/DHCP).
+ Defaults to DNSMASQ */
+ char *ipv6routing; /* path to binary for configuring IPv6 network.
+ Defaults to RADVD */
};
typedef struct _virNetworkObj virNetworkObj;
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 7d43ef5..444cbdc 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -177,7 +177,7 @@ networkFindActiveConfigs(struct network_driver *driver) {
virReportOOMError();
goto cleanup;
}
- if (virFileLinkPointsTo(pidpath, DNSMASQ) == 0)
+ if (virFileLinkPointsTo(pidpath,
obj->def->ipv4routing) == 0)
obj->dnsmasqPid = -1;
VIR_FREE(pidpath);
}
@@ -196,7 +196,7 @@ networkFindActiveConfigs(struct network_driver *driver) {
VIR_FREE(radvdpidbase);
goto cleanup;
}
- if (virFileLinkPointsTo(pidpath, RADVD) == 0)
+ if (virFileLinkPointsTo(pidpath,
obj->def->ipv6routing) == 0)
obj->radvdPid = -1;
VIR_FREE(pidpath);
}
@@ -596,7 +596,7 @@ networkStartDhcpDaemon(virNetworkObjPtr network)
goto cleanup;
}
- cmd = virCommandNew(DNSMASQ);
+ cmd = virCommandNew(network->def->ipv4routing);
if (networkBuildDnsmasqArgv(network, ipdef, pidfile, cmd) < 0) {
goto cleanup;
}
@@ -727,7 +727,7 @@ networkStartRadvd(virNetworkObjPtr network)
* its own pidfile, so we just let it do so, with a slightly
* different name. Unused, but harmless.
*/
- cmd = virCommandNewArgList(RADVD, "--debug", "1",
+ cmd = virCommandNewArgList(network->def->ipv6routing, "--debug",
"1",
"--config", configfile,
"--pidfile", NULL);
virCommandAddArgFormat(cmd, "%s-bin", pidfile);
diff --git a/tests/networkxml2xmlin/with-ipv4routing-network.xml
b/tests/networkxml2xmlin/with-ipv4routing-network.xml
new file mode 100644
index 0000000..1cf3aa4
--- /dev/null
+++ b/tests/networkxml2xmlin/with-ipv4routing-network.xml
@@ -0,0 +1,11 @@
+<network>
+ <name>private</name>
+ <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
+ <ipv4routing>/usr/local/bin/my-dnsmasq</ipv4routing>
+ <bridge name="virbr2" />
+ <ip address="192.168.152.1" netmask="255.255.255.0">
+ <dhcp>
+ <range start="192.168.152.2" end="192.168.152.254" />
+ </dhcp>
+ </ip>
+</network>
diff --git a/tests/networkxml2xmlout/with-ipv4routing-network.xml
b/tests/networkxml2xmlout/with-ipv4routing-network.xml
new file mode 100644
index 0000000..d649d78
--- /dev/null
+++ b/tests/networkxml2xmlout/with-ipv4routing-network.xml
@@ -0,0 +1,11 @@
+<network>
+ <name>private</name>
+ <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
+ <ipv4routing>/usr/local/bin/my-dnsmasq</ipv4routing>
+ <bridge name='virbr2' stp='on' delay='0' />
+ <ip address='192.168.152.1' netmask='255.255.255.0'>
+ <dhcp>
+ <range start='192.168.152.2' end='192.168.152.254' />
+ </dhcp>
+ </ip>
+</network>
diff --git a/tests/networkxml2xmltest.c b/tests/networkxml2xmltest.c
index 7805548..86e3c81 100644
--- a/tests/networkxml2xmltest.c
+++ b/tests/networkxml2xmltest.c
@@ -90,6 +90,7 @@ mymain(int argc, char **argv)
DO_TEST("nat-network");
DO_TEST("netboot-network");
DO_TEST("netboot-proxy-network");
+ DO_TEST("with-ipv4routing-network");
return (ret==0 ? EXIT_SUCCESS : EXIT_FAILURE);
}