diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in
index a9226e52ea..12d1bed1d4 100644
--- a/docs/formatnetwork.html.in
+++ b/docs/formatnetwork.html.in
@@ -260,6 +260,28 @@
Since 0.4.2
+
open
+
+ As with mode='route', guest network traffic will be
+ forwarded to the physical network via the host's IP
+ routing stack, but there will be no firewall rules added
+ to either enable or prevent any of this traffic. When
+ forward='open' is set, the dev
attribute
+ cannot be set (because the forward dev is enforced with
+ firewall rules, and the purpose of forward='open' is to
+ have a forwarding mode where libvirt doesn't add any
+ firewall rules). This mode presumes that the local LAN
+ router has suitable routing table entries to return
+ traffic to this host, and that some other management
+ system has been used to put in place any necessary
+ firewall rules. Although no firewall rules will be added
+ for the network, it is of course still possible to add
+ restrictions for specific guests using
+ nwfilter rules on the
+ guests' interfaces.)
+ Since 2.2.0
+
+
bridge
This network describes either 1) an existing host bridge
diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
index c2c51aea4d..621f16e964 100644
--- a/docs/schemas/network.rng
+++ b/docs/schemas/network.rng
@@ -103,6 +103,7 @@
nat
route
+ open
bridge
passthrough
private
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index a75ca7192c..6820bdec52 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -57,7 +57,9 @@ struct _virNetworkObjList {
VIR_ENUM_IMPL(virNetworkForward,
VIR_NETWORK_FORWARD_LAST,
- "none", "nat", "route", "bridge", "private", "vepa", "passthrough", "hostdev")
+ "none", "nat", "route", "open",
+ "bridge", "private", "vepa", "passthrough",
+ "hostdev")
VIR_ENUM_IMPL(virNetworkBridgeMACTableManager,
VIR_NETWORK_BRIDGE_MAC_TABLE_MANAGER_LAST,
@@ -2333,6 +2335,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
case VIR_NETWORK_FORWARD_ROUTE:
case VIR_NETWORK_FORWARD_NAT:
+ case VIR_NETWORK_FORWARD_OPEN:
/* It's pointless to specify L3 forwarding without specifying
* the network we're on.
*/
@@ -2351,6 +2354,19 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
def->name);
goto error;
}
+
+ if (def->forward.type == VIR_NETWORK_FORWARD_OPEN && def->forward.nifs) {
+ /* an open network by definition can't place any restrictions
+ * on what traffic is allowed or where it goes, so specifying
+ * a forwarding device is nonsensical.
+ */
+ virReportError(VIR_ERR_XML_ERROR,
+ _("forward dev not allowed for "
+ "network '%s' with forward mode='%s'"),
+ def->name,
+ virNetworkForwardTypeToString(def->forward.type));
+ goto error;
+ }
break;
case VIR_NETWORK_FORWARD_PRIVATE:
@@ -2856,13 +2872,15 @@ virNetworkDefFormatBuf(virBufferPtr buf,
if (def->forward.type == VIR_NETWORK_FORWARD_NONE ||
def->forward.type == VIR_NETWORK_FORWARD_NAT ||
def->forward.type == VIR_NETWORK_FORWARD_ROUTE ||
+ def->forward.type == VIR_NETWORK_FORWARD_OPEN ||
def->bridge || def->macTableManager) {
virBufferAddLit(buf, "bridge);
if (def->forward.type == VIR_NETWORK_FORWARD_NONE ||
def->forward.type == VIR_NETWORK_FORWARD_NAT ||
- def->forward.type == VIR_NETWORK_FORWARD_ROUTE) {
+ def->forward.type == VIR_NETWORK_FORWARD_ROUTE ||
+ def->forward.type == VIR_NETWORK_FORWARD_OPEN) {
virBufferAsprintf(buf, " stp='%s' delay='%ld'",
def->stp ? "on" : "off", def->delay);
}
@@ -3235,7 +3253,8 @@ virNetworkObjPtr virNetworkLoadConfig(virNetworkObjListPtr nets,
if (def->forward.type == VIR_NETWORK_FORWARD_NONE ||
def->forward.type == VIR_NETWORK_FORWARD_NAT ||
- def->forward.type == VIR_NETWORK_FORWARD_ROUTE) {
+ def->forward.type == VIR_NETWORK_FORWARD_ROUTE ||
+ def->forward.type == VIR_NETWORK_FORWARD_OPEN) {
if (!def->mac_specified) {
virNetworkSetBridgeMacAddr(def);
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index 78148890c2..1ce4257c34 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -46,6 +46,7 @@ typedef enum {
VIR_NETWORK_FORWARD_NONE = 0,
VIR_NETWORK_FORWARD_NAT,
VIR_NETWORK_FORWARD_ROUTE,
+ VIR_NETWORK_FORWARD_OPEN,
VIR_NETWORK_FORWARD_BRIDGE,
VIR_NETWORK_FORWARD_PRIVATE,
VIR_NETWORK_FORWARD_VEPA,
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 87019cb44f..23036e843a 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -400,6 +400,7 @@ networkUpdateState(virNetworkObjPtr obj,
case VIR_NETWORK_FORWARD_NONE:
case VIR_NETWORK_FORWARD_NAT:
case VIR_NETWORK_FORWARD_ROUTE:
+ case VIR_NETWORK_FORWARD_OPEN:
/* If bridge doesn't exist, then mark it inactive */
if (!(obj->def->bridge && virNetDevExists(obj->def->bridge) == 1))
obj->active = 0;
@@ -1822,7 +1823,8 @@ networkRefreshDaemonsHelper(virNetworkObjPtr net,
if (virNetworkObjIsActive(net) &&
((net->def->forward.type == VIR_NETWORK_FORWARD_NONE) ||
(net->def->forward.type == VIR_NETWORK_FORWARD_NAT) ||
- (net->def->forward.type == VIR_NETWORK_FORWARD_ROUTE))) {
+ (net->def->forward.type == VIR_NETWORK_FORWARD_ROUTE) ||
+ (net->def->forward.type == VIR_NETWORK_FORWARD_OPEN))) {
/* Only the three L3 network types that are configured by
* libvirt will have a dnsmasq or radvd daemon associated
* with them. Here we send a SIGHUP to an existing
@@ -1858,8 +1860,10 @@ networkReloadFirewallRulesHelper(virNetworkObjPtr net,
((net->def->forward.type == VIR_NETWORK_FORWARD_NONE) ||
(net->def->forward.type == VIR_NETWORK_FORWARD_NAT) ||
(net->def->forward.type == VIR_NETWORK_FORWARD_ROUTE))) {
- /* Only the three L3 network types that are configured by libvirt
- * need to have iptables rules reloaded.
+ /* Only three of the L3 network types that are configured by
+ * libvirt need to have iptables rules reloaded. The 4th L3
+ * network type, forward='open', doesn't need this because it
+ * has no iptables rules.
*/
networkRemoveFirewallRules(net->def);
if (networkAddFirewallRules(net->def) < 0) {
@@ -2142,7 +2146,8 @@ networkStartNetworkVirtual(virNetworkDriverStatePtr driver,
goto err1;
/* Add "once per network" rules */
- if (networkAddFirewallRules(network->def) < 0)
+ if (network->def->forward.type != VIR_NETWORK_FORWARD_OPEN &&
+ networkAddFirewallRules(network->def) < 0)
goto err1;
for (i = 0;
@@ -2244,7 +2249,8 @@ networkStartNetworkVirtual(virNetworkDriverStatePtr driver,
err2:
if (!save_err)
save_err = virSaveLastError();
- networkRemoveFirewallRules(network->def);
+ if (network->def->forward.type != VIR_NETWORK_FORWARD_OPEN)
+ networkRemoveFirewallRules(network->def);
err1:
if (!save_err)
@@ -2300,7 +2306,8 @@ networkShutdownNetworkVirtual(virNetworkDriverStatePtr driver,
ignore_value(virNetDevSetOnline(network->def->bridge, 0));
- networkRemoveFirewallRules(network->def);
+ if (network->def->forward.type != VIR_NETWORK_FORWARD_OPEN)
+ networkRemoveFirewallRules(network->def);
ignore_value(virNetDevBridgeDelete(network->def->bridge));
@@ -2407,6 +2414,7 @@ networkCreateInterfacePool(virNetworkDefPtr netdef)
case VIR_NETWORK_FORWARD_NONE:
case VIR_NETWORK_FORWARD_NAT:
case VIR_NETWORK_FORWARD_ROUTE:
+ case VIR_NETWORK_FORWARD_OPEN:
case VIR_NETWORK_FORWARD_LAST:
/* by definition these will never be encountered here */
break;
@@ -2500,6 +2508,7 @@ networkStartNetwork(virNetworkDriverStatePtr driver,
case VIR_NETWORK_FORWARD_NONE:
case VIR_NETWORK_FORWARD_NAT:
case VIR_NETWORK_FORWARD_ROUTE:
+ case VIR_NETWORK_FORWARD_OPEN:
if (networkStartNetworkVirtual(driver, network) < 0)
goto cleanup;
break;
@@ -2578,6 +2587,7 @@ networkShutdownNetwork(virNetworkDriverStatePtr driver,
case VIR_NETWORK_FORWARD_NONE:
case VIR_NETWORK_FORWARD_NAT:
case VIR_NETWORK_FORWARD_ROUTE:
+ case VIR_NETWORK_FORWARD_OPEN:
ret = networkShutdownNetworkVirtual(driver, network);
break;
@@ -2926,7 +2936,8 @@ networkValidate(virNetworkDriverStatePtr driver,
*/
if (def->forward.type == VIR_NETWORK_FORWARD_NONE ||
def->forward.type == VIR_NETWORK_FORWARD_NAT ||
- def->forward.type == VIR_NETWORK_FORWARD_ROUTE) {
+ def->forward.type == VIR_NETWORK_FORWARD_ROUTE ||
+ def->forward.type == VIR_NETWORK_FORWARD_OPEN) {
/* if no bridge name was given in the config, find a name
* unused by any other libvirt networks and assign it.
@@ -3367,8 +3378,10 @@ networkUpdate(virNetworkPtr net,
* old rules (and remember to load new ones after the
* update).
*/
- networkRemoveFirewallRules(network->def);
- needFirewallRefresh = true;
+ if (network->def->forward.type != VIR_NETWORK_FORWARD_OPEN) {
+ networkRemoveFirewallRules(network->def);
+ needFirewallRefresh = true;
+ }
break;
default:
break;
@@ -4050,7 +4063,8 @@ networkAllocateActualDevice(virDomainDefPtr dom,
if ((netdef->forward.type == VIR_NETWORK_FORWARD_NONE) ||
(netdef->forward.type == VIR_NETWORK_FORWARD_NAT) ||
- (netdef->forward.type == VIR_NETWORK_FORWARD_ROUTE)) {
+ (netdef->forward.type == VIR_NETWORK_FORWARD_ROUTE) ||
+ (netdef->forward.type == VIR_NETWORK_FORWARD_OPEN)) {
/* for these forward types, the actual net type really *is*
* NETWORK; we just keep the info from the portgroup in
* iface->data.network.actual
@@ -4594,7 +4608,8 @@ networkReleaseActualDevice(virDomainDefPtr dom,
if (iface->data.network.actual &&
(netdef->forward.type == VIR_NETWORK_FORWARD_NONE ||
netdef->forward.type == VIR_NETWORK_FORWARD_NAT ||
- netdef->forward.type == VIR_NETWORK_FORWARD_ROUTE) &&
+ netdef->forward.type == VIR_NETWORK_FORWARD_ROUTE ||
+ netdef->forward.type == VIR_NETWORK_FORWARD_OPEN) &&
networkUnplugBandwidth(network, iface) < 0)
goto error;
@@ -4741,6 +4756,7 @@ networkGetNetworkAddress(const char *netname, char **netaddr)
case VIR_NETWORK_FORWARD_NONE:
case VIR_NETWORK_FORWARD_NAT:
case VIR_NETWORK_FORWARD_ROUTE:
+ case VIR_NETWORK_FORWARD_OPEN:
ipdef = virNetworkDefGetIPByIndex(netdef, AF_UNSPEC, 0);
if (!ipdef) {
virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -4824,7 +4840,8 @@ networkGetActualType(virDomainNetDefPtr iface)
if ((netdef->forward.type == VIR_NETWORK_FORWARD_NONE) ||
(netdef->forward.type == VIR_NETWORK_FORWARD_NAT) ||
- (netdef->forward.type == VIR_NETWORK_FORWARD_ROUTE)) {
+ (netdef->forward.type == VIR_NETWORK_FORWARD_ROUTE) ||
+ (netdef->forward.type == VIR_NETWORK_FORWARD_OPEN)) {
/* for these forward types, the actual net type really *is*
* NETWORK; we just keep the info from the portgroup in
* iface->data.network.actual
diff --git a/tests/networkxml2confdata/open-network.conf b/tests/networkxml2confdata/open-network.conf
new file mode 100644
index 0000000000..ff099847d4
--- /dev/null
+++ b/tests/networkxml2confdata/open-network.conf
@@ -0,0 +1,11 @@
+##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 open
+## or other application using the libvirt API.
+##
+## dnsmasq conf file created by libvirt
+strict-order
+except-interface=lo
+bind-dynamic
+interface=virbr1
+addn-hosts=/var/lib/libvirt/dnsmasq/open.addnhosts
diff --git a/tests/networkxml2confdata/open-network.xml b/tests/networkxml2confdata/open-network.xml
new file mode 100644
index 0000000000..e0b3f039f4
--- /dev/null
+++ b/tests/networkxml2confdata/open-network.xml
@@ -0,0 +1,9 @@
+
+ open
+ 81ff0d90-c91e-6742-64da-4a736edb9a9b
+
+
+
+
+
+
diff --git a/tests/networkxml2conftest.c b/tests/networkxml2conftest.c
index 69b55ed53c..a4223108f1 100644
--- a/tests/networkxml2conftest.c
+++ b/tests/networkxml2conftest.c
@@ -117,6 +117,7 @@ mymain(void)
DO_TEST("nat-network-dns-srv-record-minimal", restricted);
DO_TEST("nat-network-name-with-quotes", restricted);
DO_TEST("routed-network", full);
+ DO_TEST("open-network", full);
DO_TEST("nat-network", dhcpv6);
DO_TEST("nat-network-dns-txt-record", full);
DO_TEST("nat-network-dns-srv-record", full);
diff --git a/tests/networkxml2xmlin/open-network-with-forward-dev.xml b/tests/networkxml2xmlin/open-network-with-forward-dev.xml
new file mode 100644
index 0000000000..33e8bb58b5
--- /dev/null
+++ b/tests/networkxml2xmlin/open-network-with-forward-dev.xml
@@ -0,0 +1,9 @@
+
+ open
+ 81ff0d90-c91e-6742-64da-4a736edb9a9b
+
+
+
+
+
+
diff --git a/tests/networkxml2xmlin/open-network.xml b/tests/networkxml2xmlin/open-network.xml
new file mode 100644
index 0000000000..2e4b9b282e
--- /dev/null
+++ b/tests/networkxml2xmlin/open-network.xml
@@ -0,0 +1,9 @@
+
+ open
+ 81ff0d90-c91e-6742-64da-4a736edb9a9b
+
+
+
+
+
+
diff --git a/tests/networkxml2xmlout/open-network.xml b/tests/networkxml2xmlout/open-network.xml
new file mode 100644
index 0000000000..29e968442b
--- /dev/null
+++ b/tests/networkxml2xmlout/open-network.xml
@@ -0,0 +1,9 @@
+
+ open
+ 81ff0d90-c91e-6742-64da-4a736edb9a9b
+
+
+
+
+
+
diff --git a/tests/networkxml2xmltest.c b/tests/networkxml2xmltest.c
index 2a2c348430..32544d0568 100644
--- a/tests/networkxml2xmltest.c
+++ b/tests/networkxml2xmltest.c
@@ -127,6 +127,8 @@ mymain(void)
DO_TEST("empty-allow-ipv6");
DO_TEST("isolated-network");
DO_TEST("routed-network");
+ DO_TEST("open-network");
+ DO_TEST_PARSE_ERROR("open-network-with-forward-dev");
DO_TEST("nat-network");
DO_TEST("netboot-network");
DO_TEST("netboot-proxy-network");