]> xenbits.xensource.com Git - libvirt.git/commitdiff
network: split setup of ipv4 and ipv6 top level chains
authorDaniel P. Berrangé <berrange@redhat.com>
Mon, 18 Mar 2019 16:49:32 +0000 (16:49 +0000)
committerDaniel P. Berrangé <berrange@redhat.com>
Tue, 19 Mar 2019 10:01:53 +0000 (10:01 +0000)
During startup libvirtd creates top level chains for both ipv4
and ipv6 protocols. If this fails for any reason then startup
of virtual networks is blocked.

The default virtual network, however, only requires use of ipv4
and some servers have ipv6 disabled so it is expected that ipv6
chain creation will fail. There could equally be servers with
no ipv4, only ipv6.

This patch thus makes error reporting a little more fine grained
so that it works more sensibly when either ipv4 or ipv6 is
disabled on the server. Only the protocols that are actually
used by the virtual network have errors reported.

Reviewed-by: Andrea Bolognani <abologna@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
src/network/bridge_driver_linux.c
src/util/viriptables.c
src/util/viriptables.h

index c899f4b6d0ec45e6c49ab07669e1e9970c5f5c8c..50fc197134030101ef32a96b6c354d756f7ffe64 100644 (file)
@@ -35,10 +35,12 @@ VIR_LOG_INIT("network.bridge_driver_linux");
 
 #define PROC_NET_ROUTE "/proc/net/route"
 
-static virErrorPtr errInit;
+static virErrorPtr errInitV4;
+static virErrorPtr errInitV6;
 
 void networkPreReloadFirewallRules(bool startup)
 {
+    bool created = false;
     int rc;
 
     /* We create global rules upfront as we don't want
@@ -49,11 +51,21 @@ void networkPreReloadFirewallRules(bool startup)
      * of starting the network though as that makes them
      * more likely to be seen by a human
      */
-    rc = iptablesSetupPrivateChains();
+    rc = iptablesSetupPrivateChains(VIR_FIREWALL_LAYER_IPV4);
     if (rc < 0) {
-        errInit = virSaveLastError();
+        errInitV4 = virSaveLastError();
         virResetLastError();
     }
+    if (rc)
+        created = true;
+
+    rc = iptablesSetupPrivateChains(VIR_FIREWALL_LAYER_IPV6);
+    if (rc < 0) {
+        errInitV6 = virSaveLastError();
+        virResetLastError();
+    }
+    if (rc)
+        created = true;
 
     /*
      * If this is initial startup, and we just created the
@@ -68,7 +80,7 @@ void networkPreReloadFirewallRules(bool startup)
      * rules will be present. Thus we can safely just tell it
      * to always delete from the builin chain
      */
-    if (startup && rc == 1)
+    if (startup && created)
         iptablesSetDeletePrivate(false);
 }
 
@@ -683,8 +695,18 @@ int networkAddFirewallRules(virNetworkDefPtr def)
     virFirewallPtr fw = NULL;
     int ret = -1;
 
-    if (errInit) {
-        virSetError(errInit);
+    if (errInitV4 &&
+        (virNetworkDefGetIPByIndex(def, AF_INET, 0) ||
+         virNetworkDefGetRouteByIndex(def, AF_INET, 0))) {
+        virSetError(errInitV4);
+        return -1;
+    }
+
+    if (errInitV6 &&
+        (virNetworkDefGetIPByIndex(def, AF_INET6, 0) ||
+         virNetworkDefGetRouteByIndex(def, AF_INET6, 0) ||
+         def->ipv6nogw)) {
+        virSetError(errInitV6);
         return -1;
     }
 
index d67b640a3bdafb81fe1aaa879ca6534d193140c3..0e3c0ad73a63016347afd4b9a8be31310bb629da 100644 (file)
@@ -127,7 +127,7 @@ iptablesPrivateChainCreate(virFirewallPtr fw,
 
 
 int
-iptablesSetupPrivateChains(void)
+iptablesSetupPrivateChains(virFirewallLayer layer)
 {
     virFirewallPtr fw = NULL;
     int ret = -1;
@@ -143,17 +143,11 @@ iptablesSetupPrivateChains(void)
     };
     bool changed = false;
     iptablesGlobalChainData data[] = {
-        { VIR_FIREWALL_LAYER_IPV4, "filter",
+        { layer, "filter",
           filter_chains, ARRAY_CARDINALITY(filter_chains), &changed },
-        { VIR_FIREWALL_LAYER_IPV4, "nat",
+        { layer, "nat",
           natmangle_chains, ARRAY_CARDINALITY(natmangle_chains), &changed },
-        { VIR_FIREWALL_LAYER_IPV4, "mangle",
-          natmangle_chains, ARRAY_CARDINALITY(natmangle_chains), &changed },
-        { VIR_FIREWALL_LAYER_IPV6, "filter",
-          filter_chains, ARRAY_CARDINALITY(filter_chains), &changed },
-        { VIR_FIREWALL_LAYER_IPV6, "nat",
-          natmangle_chains, ARRAY_CARDINALITY(natmangle_chains), &changed },
-        { VIR_FIREWALL_LAYER_IPV6, "mangle",
+        { layer, "mangle",
           natmangle_chains, ARRAY_CARDINALITY(natmangle_chains), &changed },
     };
     size_t i;
index 903f390f898249fd5e0b1d8f123b89fbaea1ee94..e680407ec827513586c357600dfdce7b7c2e6f94 100644 (file)
@@ -24,7 +24,7 @@
 # include "virsocketaddr.h"
 # include "virfirewall.h"
 
-int              iptablesSetupPrivateChains      (void);
+int              iptablesSetupPrivateChains      (virFirewallLayer layer);
 
 void             iptablesSetDeletePrivate        (bool pvt);