[libvirt] [v2 1/3] Clean all tables before applying basic rules

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The functions invoked by the IP address learning thread
that apply some basic filtering rules did not clean up
any previous filtering rules that may still be there
(due to a libvirt restart for example). With the
patch below all the rules are cleaned up first.

Also, I am introducing a function to drop all traffic 
in case the IP address learning thread could not apply
the rules.

Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxx>

---
 src/conf/nwfilter_conf.h                  |    3 
 src/nwfilter/nwfilter_ebiptables_driver.c |  104 +++++++++++++++++++++++++-----
 src/nwfilter/nwfilter_learnipaddr.c       |    4 -
 src/nwfilter/nwfilter_learnipaddr.h       |    2 
 4 files changed, 96 insertions(+), 17 deletions(-)

Index: libvirt-acl/src/nwfilter/nwfilter_ebiptables_driver.c
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_ebiptables_driver.c
+++ libvirt-acl/src/nwfilter/nwfilter_ebiptables_driver.c
@@ -102,6 +102,7 @@ static const char *m_physdev_out_str = "
 static int ebtablesRemoveBasicRules(const char *ifname);
 static int ebiptablesDriverInit(void);
 static void ebiptablesDriverShutdown(void);
+static int ebtablesCleanAll(const char *ifname);
 
 
 struct ushort_map {
@@ -2679,12 +2680,7 @@ ebtablesApplyBasicRules(const char *ifna
 
     virFormatMacAddr(macaddr, macaddr_str);
 
-    ebtablesUnlinkTmpRootChain(&buf, 1, ifname);
-    ebtablesUnlinkTmpRootChain(&buf, 0, ifname);
-    ebtablesRemoveTmpSubChains(&buf, ifname);
-    ebtablesRemoveTmpRootChain(&buf, 1, ifname);
-    ebtablesRemoveTmpRootChain(&buf, 0, ifname);
-    ebiptablesExecCLI(&buf, &cli_status);
+    ebtablesCleanAll(ifname);
 
     ebtablesCreateTmpRootChain(&buf, 1, ifname, 1);
 
@@ -2723,6 +2719,7 @@ ebtablesApplyBasicRules(const char *ifna
                       CMD_STOPONERR(1));
 
     ebtablesLinkTmpRootChain(&buf, 1, ifname, 1);
+    ebtablesRenameTmpRootChain(&buf, 1, ifname);
 
     if (ebiptablesExecCLI(&buf, &cli_status) || cli_status != 0)
         goto tear_down_tmpebchains;
@@ -2730,7 +2727,7 @@ ebtablesApplyBasicRules(const char *ifna
     return 0;
 
 tear_down_tmpebchains:
-    ebtablesRemoveBasicRules(ifname);
+    ebtablesCleanAll(ifname);
 
     virNWFilterReportError(VIR_ERR_BUILD_FIREWALL,
                            "%s",
@@ -2782,12 +2779,7 @@ ebtablesApplyDHCPOnlyRules(const char *i
 
     virFormatMacAddr(macaddr, macaddr_str);
 
-    ebtablesUnlinkTmpRootChain(&buf, 1, ifname);
-    ebtablesUnlinkTmpRootChain(&buf, 0, ifname);
-    ebtablesRemoveTmpSubChains(&buf, ifname);
-    ebtablesRemoveTmpRootChain(&buf, 1, ifname);
-    ebtablesRemoveTmpRootChain(&buf, 0, ifname);
-    ebiptablesExecCLI(&buf, &cli_status);
+    ebtablesCleanAll(ifname);
 
     ebtablesCreateTmpRootChain(&buf, 1, ifname, 1);
     ebtablesCreateTmpRootChain(&buf, 0, ifname, 1);
@@ -2842,6 +2834,8 @@ ebtablesApplyDHCPOnlyRules(const char *i
 
     ebtablesLinkTmpRootChain(&buf, 1, ifname, 1);
     ebtablesLinkTmpRootChain(&buf, 0, ifname, 1);
+    ebtablesRenameTmpRootChain(&buf, 1, ifname);
+    ebtablesRenameTmpRootChain(&buf, 0, ifname);
 
     if (ebiptablesExecCLI(&buf, &cli_status) || cli_status != 0)
         goto tear_down_tmpebchains;
@@ -2851,7 +2845,7 @@ ebtablesApplyDHCPOnlyRules(const char *i
     return 0;
 
 tear_down_tmpebchains:
-    ebtablesRemoveBasicRules(ifname);
+    ebtablesCleanAll(ifname);
 
     virNWFilterReportError(VIR_ERR_BUILD_FIREWALL,
                            "%s",
@@ -2863,15 +2857,96 @@ tear_down_tmpebchains:
 }
 
 
+/**
+ * ebtablesApplyDropAllRules
+ *
+ * @ifname: name of the backend-interface to which to apply the rules
+ *
+ * Returns 0 on success, 1 on failure with the rules removed
+ *
+ * Apply filtering rules so that the VM cannot receive or send traffic.
+ */
+static int
+ebtablesApplyDropAllRules(const char *ifname)
+{
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+    int cli_status;
+    char chain_in [MAX_CHAINNAME_LENGTH],
+         chain_out[MAX_CHAINNAME_LENGTH];
+
+    if (!ebtables_cmd_path) {
+        virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                               _("cannot create rules since ebtables tool is "
+                                 "missing."));
+        return 1;
+    }
+
+    ebtablesCleanAll(ifname);
+
+    ebtablesCreateTmpRootChain(&buf, 1, ifname, 1);
+    ebtablesCreateTmpRootChain(&buf, 0, ifname, 1);
+
+    PRINT_ROOT_CHAIN(chain_in , CHAINPREFIX_HOST_IN_TEMP , ifname);
+    PRINT_ROOT_CHAIN(chain_out, CHAINPREFIX_HOST_OUT_TEMP, ifname);
+
+    virBufferVSprintf(&buf,
+                      CMD_DEF("%s -t %s -A %s -j DROP") CMD_SEPARATOR
+                      CMD_EXEC
+                      "%s",
+
+                      ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, chain_in,
+                      CMD_STOPONERR(1));
+
+    virBufferVSprintf(&buf,
+                      CMD_DEF("%s -t %s -A %s -j DROP") CMD_SEPARATOR
+                      CMD_EXEC
+                      "%s",
+
+                      ebtables_cmd_path, EBTABLES_DEFAULT_TABLE, chain_out,
+                      CMD_STOPONERR(1));
+
+    ebtablesLinkTmpRootChain(&buf, 1, ifname, 1);
+    ebtablesLinkTmpRootChain(&buf, 0, ifname, 1);
+    ebtablesRenameTmpRootChain(&buf, 1, ifname);
+    ebtablesRenameTmpRootChain(&buf, 0, ifname);
+
+    if (ebiptablesExecCLI(&buf, &cli_status) || cli_status != 0)
+        goto tear_down_tmpebchains;
+
+    return 0;
+
+tear_down_tmpebchains:
+    ebtablesCleanAll(ifname);
+
+    virNWFilterReportError(VIR_ERR_BUILD_FIREWALL,
+                           "%s",
+                           _("Some rules could not be created."));
+
+    return 1;
+}
+
+
 static int
 ebtablesRemoveBasicRules(const char *ifname)
 {
+    return ebtablesCleanAll(ifname);
+}
+
+
+static int ebtablesCleanAll(const char *ifname)
+{
     virBuffer buf = VIR_BUFFER_INITIALIZER;
     int cli_status;
 
     if (!ebtables_cmd_path)
         return 0;
 
+    ebtablesUnlinkRootChain(&buf, 1, ifname);
+    ebtablesUnlinkRootChain(&buf, 0, ifname);
+    ebtablesRemoveSubChains(&buf, ifname);
+    ebtablesRemoveRootChain(&buf, 1, ifname);
+    ebtablesRemoveRootChain(&buf, 0, ifname);
+
     ebtablesUnlinkTmpRootChain(&buf, 1, ifname);
     ebtablesUnlinkTmpRootChain(&buf, 0, ifname);
     ebtablesRemoveTmpSubChains(&buf, ifname);
@@ -3265,6 +3340,7 @@ virNWFilterTechDriver ebiptables_driver 
     .canApplyBasicRules  = ebiptablesCanApplyBasicRules,
     .applyBasicRules     = ebtablesApplyBasicRules,
     .applyDHCPOnlyRules  = ebtablesApplyDHCPOnlyRules,
+    .applyDropAllRules   = ebtablesApplyDropAllRules,
     .removeBasicRules    = ebtablesRemoveBasicRules,
 };
 
Index: libvirt-acl/src/nwfilter/nwfilter_learnipaddr.c
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_learnipaddr.c
+++ libvirt-acl/src/nwfilter/nwfilter_learnipaddr.c
@@ -598,8 +598,6 @@ learnIPAddressThread(void *arg)
     if (handle)
         pcap_close(handle);
 
-    techdriver->removeBasicRules(req->ifname);
-
     if (req->status == 0) {
         int ret;
         char inetaddr[INET_ADDRSTRLEN];
@@ -624,6 +622,8 @@ learnIPAddressThread(void *arg)
                                  _("encountered an error on interface %s "
                                    "index %d"),
                                  req->ifname, req->ifindex);
+
+        techdriver->applyDropAllRules(req->ifname);
     }
 
     memset(&req->thread, 0x0, sizeof(req->thread));
Index: libvirt-acl/src/conf/nwfilter_conf.h
===================================================================
--- libvirt-acl.orig/src/conf/nwfilter_conf.h
+++ libvirt-acl/src/conf/nwfilter_conf.h
@@ -521,6 +521,8 @@ typedef int (*virNWFilterApplyDHCPOnlyRu
 
 typedef int (*virNWFilterRemoveBasicRules)(const char *ifname);
 
+typedef int (*virNWFilterDropAllRules)(const char *ifname);
+
 enum techDrvFlags {
     TECHDRV_FLAG_INITIALIZED = (1 << 0),
 };
@@ -544,6 +546,7 @@ struct _virNWFilterTechDriver {
     virNWFilterCanApplyBasicRules canApplyBasicRules;
     virNWFilterApplyBasicRules applyBasicRules;
     virNWFilterApplyDHCPOnlyRules applyDHCPOnlyRules;
+    virNWFilterDropAllRules applyDropAllRules;
     virNWFilterRemoveBasicRules removeBasicRules;
 };
 
Index: libvirt-acl/src/nwfilter/nwfilter_learnipaddr.h
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_learnipaddr.h
+++ libvirt-acl/src/nwfilter/nwfilter_learnipaddr.h
@@ -60,7 +60,7 @@ int virNWFilterLearnIPAddress(virNWFilte
                               enum howDetect howDetect);
 
 virNWFilterIPAddrLearnReqPtr virNWFilterLookupLearnReq(int ifindex);
-
+int virNWFilterTerminateLearnReq(const char *ifname);
 
 void virNWFilterDelIpAddrForIfname(const char *ifname);
 const char *virNWFilterGetIpAddrForIfname(const char *ifname);

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list

[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]