提交 25e8112d 编写于 作者: L Laine Stump

network: new network forward mode 'open'

The new forward mode 'open' is just like mode='route', except that no
firewall rules are added to assure that any traffic does or doesn't
pass. It is assumed that either they aren't necessary, or they will be
setup outside the scope of libvirt.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=846810
上级 5dd3aa2d
...@@ -260,6 +260,28 @@ ...@@ -260,6 +260,28 @@
<span class="since">Since 0.4.2</span> <span class="since">Since 0.4.2</span>
</dd> </dd>
<dt><code>open</code></dt>
<dd>
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 <code>dev</code> 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
<a href="formatnwfilter.html">nwfilter rules</a> on the
guests' interfaces.)
<span class="since">Since 2.2.0</span>
</dd>
<dt><code>bridge</code></dt> <dt><code>bridge</code></dt>
<dd> <dd>
This network describes either 1) an existing host bridge This network describes either 1) an existing host bridge
......
...@@ -103,6 +103,7 @@ ...@@ -103,6 +103,7 @@
<choice> <choice>
<value>nat</value> <value>nat</value>
<value>route</value> <value>route</value>
<value>open</value>
<value>bridge</value> <value>bridge</value>
<value>passthrough</value> <value>passthrough</value>
<value>private</value> <value>private</value>
......
...@@ -57,7 +57,9 @@ struct _virNetworkObjList { ...@@ -57,7 +57,9 @@ struct _virNetworkObjList {
VIR_ENUM_IMPL(virNetworkForward, VIR_ENUM_IMPL(virNetworkForward,
VIR_NETWORK_FORWARD_LAST, 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_ENUM_IMPL(virNetworkBridgeMACTableManager,
VIR_NETWORK_BRIDGE_MAC_TABLE_MANAGER_LAST, VIR_NETWORK_BRIDGE_MAC_TABLE_MANAGER_LAST,
...@@ -2333,6 +2335,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt) ...@@ -2333,6 +2335,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
case VIR_NETWORK_FORWARD_ROUTE: case VIR_NETWORK_FORWARD_ROUTE:
case VIR_NETWORK_FORWARD_NAT: case VIR_NETWORK_FORWARD_NAT:
case VIR_NETWORK_FORWARD_OPEN:
/* It's pointless to specify L3 forwarding without specifying /* It's pointless to specify L3 forwarding without specifying
* the network we're on. * the network we're on.
*/ */
...@@ -2351,6 +2354,19 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt) ...@@ -2351,6 +2354,19 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
def->name); def->name);
goto error; 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; break;
case VIR_NETWORK_FORWARD_PRIVATE: case VIR_NETWORK_FORWARD_PRIVATE:
...@@ -2856,13 +2872,15 @@ virNetworkDefFormatBuf(virBufferPtr buf, ...@@ -2856,13 +2872,15 @@ virNetworkDefFormatBuf(virBufferPtr buf,
if (def->forward.type == VIR_NETWORK_FORWARD_NONE || if (def->forward.type == VIR_NETWORK_FORWARD_NONE ||
def->forward.type == VIR_NETWORK_FORWARD_NAT || 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 ||
def->bridge || def->macTableManager) { def->bridge || def->macTableManager) {
virBufferAddLit(buf, "<bridge"); virBufferAddLit(buf, "<bridge");
virBufferEscapeString(buf, " name='%s'", def->bridge); virBufferEscapeString(buf, " name='%s'", def->bridge);
if (def->forward.type == VIR_NETWORK_FORWARD_NONE || if (def->forward.type == VIR_NETWORK_FORWARD_NONE ||
def->forward.type == VIR_NETWORK_FORWARD_NAT || 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'", virBufferAsprintf(buf, " stp='%s' delay='%ld'",
def->stp ? "on" : "off", def->delay); def->stp ? "on" : "off", def->delay);
} }
...@@ -3235,7 +3253,8 @@ virNetworkObjPtr virNetworkLoadConfig(virNetworkObjListPtr nets, ...@@ -3235,7 +3253,8 @@ virNetworkObjPtr virNetworkLoadConfig(virNetworkObjListPtr nets,
if (def->forward.type == VIR_NETWORK_FORWARD_NONE || if (def->forward.type == VIR_NETWORK_FORWARD_NONE ||
def->forward.type == VIR_NETWORK_FORWARD_NAT || 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) { if (!def->mac_specified) {
virNetworkSetBridgeMacAddr(def); virNetworkSetBridgeMacAddr(def);
......
...@@ -46,6 +46,7 @@ typedef enum { ...@@ -46,6 +46,7 @@ typedef enum {
VIR_NETWORK_FORWARD_NONE = 0, VIR_NETWORK_FORWARD_NONE = 0,
VIR_NETWORK_FORWARD_NAT, VIR_NETWORK_FORWARD_NAT,
VIR_NETWORK_FORWARD_ROUTE, VIR_NETWORK_FORWARD_ROUTE,
VIR_NETWORK_FORWARD_OPEN,
VIR_NETWORK_FORWARD_BRIDGE, VIR_NETWORK_FORWARD_BRIDGE,
VIR_NETWORK_FORWARD_PRIVATE, VIR_NETWORK_FORWARD_PRIVATE,
VIR_NETWORK_FORWARD_VEPA, VIR_NETWORK_FORWARD_VEPA,
......
...@@ -400,6 +400,7 @@ networkUpdateState(virNetworkObjPtr obj, ...@@ -400,6 +400,7 @@ networkUpdateState(virNetworkObjPtr obj,
case VIR_NETWORK_FORWARD_NONE: case VIR_NETWORK_FORWARD_NONE:
case VIR_NETWORK_FORWARD_NAT: case VIR_NETWORK_FORWARD_NAT:
case VIR_NETWORK_FORWARD_ROUTE: case VIR_NETWORK_FORWARD_ROUTE:
case VIR_NETWORK_FORWARD_OPEN:
/* If bridge doesn't exist, then mark it inactive */ /* If bridge doesn't exist, then mark it inactive */
if (!(obj->def->bridge && virNetDevExists(obj->def->bridge) == 1)) if (!(obj->def->bridge && virNetDevExists(obj->def->bridge) == 1))
obj->active = 0; obj->active = 0;
...@@ -1822,7 +1823,8 @@ networkRefreshDaemonsHelper(virNetworkObjPtr net, ...@@ -1822,7 +1823,8 @@ networkRefreshDaemonsHelper(virNetworkObjPtr net,
if (virNetworkObjIsActive(net) && if (virNetworkObjIsActive(net) &&
((net->def->forward.type == VIR_NETWORK_FORWARD_NONE) || ((net->def->forward.type == VIR_NETWORK_FORWARD_NONE) ||
(net->def->forward.type == VIR_NETWORK_FORWARD_NAT) || (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 /* Only the three L3 network types that are configured by
* libvirt will have a dnsmasq or radvd daemon associated * libvirt will have a dnsmasq or radvd daemon associated
* with them. Here we send a SIGHUP to an existing * with them. Here we send a SIGHUP to an existing
...@@ -1858,8 +1860,10 @@ networkReloadFirewallRulesHelper(virNetworkObjPtr net, ...@@ -1858,8 +1860,10 @@ networkReloadFirewallRulesHelper(virNetworkObjPtr net,
((net->def->forward.type == VIR_NETWORK_FORWARD_NONE) || ((net->def->forward.type == VIR_NETWORK_FORWARD_NONE) ||
(net->def->forward.type == VIR_NETWORK_FORWARD_NAT) || (net->def->forward.type == VIR_NETWORK_FORWARD_NAT) ||
(net->def->forward.type == VIR_NETWORK_FORWARD_ROUTE))) { (net->def->forward.type == VIR_NETWORK_FORWARD_ROUTE))) {
/* Only the three L3 network types that are configured by libvirt /* Only three of the L3 network types that are configured by
* need to have iptables rules reloaded. * 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); networkRemoveFirewallRules(net->def);
if (networkAddFirewallRules(net->def) < 0) { if (networkAddFirewallRules(net->def) < 0) {
...@@ -2142,7 +2146,8 @@ networkStartNetworkVirtual(virNetworkDriverStatePtr driver, ...@@ -2142,7 +2146,8 @@ networkStartNetworkVirtual(virNetworkDriverStatePtr driver,
goto err1; goto err1;
/* Add "once per network" rules */ /* 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; goto err1;
for (i = 0; for (i = 0;
...@@ -2244,7 +2249,8 @@ networkStartNetworkVirtual(virNetworkDriverStatePtr driver, ...@@ -2244,7 +2249,8 @@ networkStartNetworkVirtual(virNetworkDriverStatePtr driver,
err2: err2:
if (!save_err) if (!save_err)
save_err = virSaveLastError(); save_err = virSaveLastError();
networkRemoveFirewallRules(network->def); if (network->def->forward.type != VIR_NETWORK_FORWARD_OPEN)
networkRemoveFirewallRules(network->def);
err1: err1:
if (!save_err) if (!save_err)
...@@ -2300,7 +2306,8 @@ networkShutdownNetworkVirtual(virNetworkDriverStatePtr driver, ...@@ -2300,7 +2306,8 @@ networkShutdownNetworkVirtual(virNetworkDriverStatePtr driver,
ignore_value(virNetDevSetOnline(network->def->bridge, 0)); 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)); ignore_value(virNetDevBridgeDelete(network->def->bridge));
...@@ -2407,6 +2414,7 @@ networkCreateInterfacePool(virNetworkDefPtr netdef) ...@@ -2407,6 +2414,7 @@ networkCreateInterfacePool(virNetworkDefPtr netdef)
case VIR_NETWORK_FORWARD_NONE: case VIR_NETWORK_FORWARD_NONE:
case VIR_NETWORK_FORWARD_NAT: case VIR_NETWORK_FORWARD_NAT:
case VIR_NETWORK_FORWARD_ROUTE: case VIR_NETWORK_FORWARD_ROUTE:
case VIR_NETWORK_FORWARD_OPEN:
case VIR_NETWORK_FORWARD_LAST: case VIR_NETWORK_FORWARD_LAST:
/* by definition these will never be encountered here */ /* by definition these will never be encountered here */
break; break;
...@@ -2500,6 +2508,7 @@ networkStartNetwork(virNetworkDriverStatePtr driver, ...@@ -2500,6 +2508,7 @@ networkStartNetwork(virNetworkDriverStatePtr driver,
case VIR_NETWORK_FORWARD_NONE: case VIR_NETWORK_FORWARD_NONE:
case VIR_NETWORK_FORWARD_NAT: case VIR_NETWORK_FORWARD_NAT:
case VIR_NETWORK_FORWARD_ROUTE: case VIR_NETWORK_FORWARD_ROUTE:
case VIR_NETWORK_FORWARD_OPEN:
if (networkStartNetworkVirtual(driver, network) < 0) if (networkStartNetworkVirtual(driver, network) < 0)
goto cleanup; goto cleanup;
break; break;
...@@ -2578,6 +2587,7 @@ networkShutdownNetwork(virNetworkDriverStatePtr driver, ...@@ -2578,6 +2587,7 @@ networkShutdownNetwork(virNetworkDriverStatePtr driver,
case VIR_NETWORK_FORWARD_NONE: case VIR_NETWORK_FORWARD_NONE:
case VIR_NETWORK_FORWARD_NAT: case VIR_NETWORK_FORWARD_NAT:
case VIR_NETWORK_FORWARD_ROUTE: case VIR_NETWORK_FORWARD_ROUTE:
case VIR_NETWORK_FORWARD_OPEN:
ret = networkShutdownNetworkVirtual(driver, network); ret = networkShutdownNetworkVirtual(driver, network);
break; break;
...@@ -2926,7 +2936,8 @@ networkValidate(virNetworkDriverStatePtr driver, ...@@ -2926,7 +2936,8 @@ networkValidate(virNetworkDriverStatePtr driver,
*/ */
if (def->forward.type == VIR_NETWORK_FORWARD_NONE || if (def->forward.type == VIR_NETWORK_FORWARD_NONE ||
def->forward.type == VIR_NETWORK_FORWARD_NAT || 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 /* if no bridge name was given in the config, find a name
* unused by any other libvirt networks and assign it. * unused by any other libvirt networks and assign it.
...@@ -3367,8 +3378,10 @@ networkUpdate(virNetworkPtr net, ...@@ -3367,8 +3378,10 @@ networkUpdate(virNetworkPtr net,
* old rules (and remember to load new ones after the * old rules (and remember to load new ones after the
* update). * update).
*/ */
networkRemoveFirewallRules(network->def); if (network->def->forward.type != VIR_NETWORK_FORWARD_OPEN) {
needFirewallRefresh = true; networkRemoveFirewallRules(network->def);
needFirewallRefresh = true;
}
break; break;
default: default:
break; break;
...@@ -4050,7 +4063,8 @@ networkAllocateActualDevice(virDomainDefPtr dom, ...@@ -4050,7 +4063,8 @@ networkAllocateActualDevice(virDomainDefPtr dom,
if ((netdef->forward.type == VIR_NETWORK_FORWARD_NONE) || if ((netdef->forward.type == VIR_NETWORK_FORWARD_NONE) ||
(netdef->forward.type == VIR_NETWORK_FORWARD_NAT) || (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* /* for these forward types, the actual net type really *is*
* NETWORK; we just keep the info from the portgroup in * NETWORK; we just keep the info from the portgroup in
* iface->data.network.actual * iface->data.network.actual
...@@ -4594,7 +4608,8 @@ networkReleaseActualDevice(virDomainDefPtr dom, ...@@ -4594,7 +4608,8 @@ networkReleaseActualDevice(virDomainDefPtr dom,
if (iface->data.network.actual && if (iface->data.network.actual &&
(netdef->forward.type == VIR_NETWORK_FORWARD_NONE || (netdef->forward.type == VIR_NETWORK_FORWARD_NONE ||
netdef->forward.type == VIR_NETWORK_FORWARD_NAT || 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) networkUnplugBandwidth(network, iface) < 0)
goto error; goto error;
...@@ -4741,6 +4756,7 @@ networkGetNetworkAddress(const char *netname, char **netaddr) ...@@ -4741,6 +4756,7 @@ networkGetNetworkAddress(const char *netname, char **netaddr)
case VIR_NETWORK_FORWARD_NONE: case VIR_NETWORK_FORWARD_NONE:
case VIR_NETWORK_FORWARD_NAT: case VIR_NETWORK_FORWARD_NAT:
case VIR_NETWORK_FORWARD_ROUTE: case VIR_NETWORK_FORWARD_ROUTE:
case VIR_NETWORK_FORWARD_OPEN:
ipdef = virNetworkDefGetIPByIndex(netdef, AF_UNSPEC, 0); ipdef = virNetworkDefGetIPByIndex(netdef, AF_UNSPEC, 0);
if (!ipdef) { if (!ipdef) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
...@@ -4824,7 +4840,8 @@ networkGetActualType(virDomainNetDefPtr iface) ...@@ -4824,7 +4840,8 @@ networkGetActualType(virDomainNetDefPtr iface)
if ((netdef->forward.type == VIR_NETWORK_FORWARD_NONE) || if ((netdef->forward.type == VIR_NETWORK_FORWARD_NONE) ||
(netdef->forward.type == VIR_NETWORK_FORWARD_NAT) || (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* /* for these forward types, the actual net type really *is*
* NETWORK; we just keep the info from the portgroup in * NETWORK; we just keep the info from the portgroup in
* iface->data.network.actual * iface->data.network.actual
......
##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
<network>
<name>open</name>
<uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
<forward mode='open'/>
<bridge name='virbr1' stp='on' delay='0'/>
<mac address='12:34:56:78:9A:BC'/>
<ip address='192.168.122.1' netmask='255.255.255.0'>
</ip>
</network>
...@@ -117,6 +117,7 @@ mymain(void) ...@@ -117,6 +117,7 @@ mymain(void)
DO_TEST("nat-network-dns-srv-record-minimal", restricted); DO_TEST("nat-network-dns-srv-record-minimal", restricted);
DO_TEST("nat-network-name-with-quotes", restricted); DO_TEST("nat-network-name-with-quotes", restricted);
DO_TEST("routed-network", full); DO_TEST("routed-network", full);
DO_TEST("open-network", full);
DO_TEST("nat-network", dhcpv6); DO_TEST("nat-network", dhcpv6);
DO_TEST("nat-network-dns-txt-record", full); DO_TEST("nat-network-dns-txt-record", full);
DO_TEST("nat-network-dns-srv-record", full); DO_TEST("nat-network-dns-srv-record", full);
......
<network>
<name>open</name>
<uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
<bridge name="virbr1"/>
<mac address='12:34:56:78:9A:BC'/>
<forward mode="open" dev="eth0"/>
<ip address="192.168.122.1" netmask="255.255.255.0">
</ip>
</network>
<network>
<name>open</name>
<uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
<bridge name="virbr1"/>
<mac address='12:34:56:78:9A:BC'/>
<forward mode="open"/>
<ip address="192.168.122.1" netmask="255.255.255.0">
</ip>
</network>
<network>
<name>open</name>
<uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
<forward mode='open'/>
<bridge name='virbr1' stp='on' delay='0'/>
<mac address='12:34:56:78:9a:bc'/>
<ip address='192.168.122.1' netmask='255.255.255.0'>
</ip>
</network>
...@@ -127,6 +127,8 @@ mymain(void) ...@@ -127,6 +127,8 @@ mymain(void)
DO_TEST("empty-allow-ipv6"); DO_TEST("empty-allow-ipv6");
DO_TEST("isolated-network"); DO_TEST("isolated-network");
DO_TEST("routed-network"); DO_TEST("routed-network");
DO_TEST("open-network");
DO_TEST_PARSE_ERROR("open-network-with-forward-dev");
DO_TEST("nat-network"); DO_TEST("nat-network");
DO_TEST("netboot-network"); DO_TEST("netboot-network");
DO_TEST("netboot-proxy-network"); DO_TEST("netboot-proxy-network");
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册