aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Berger <stefanb@us.ibm.com>2010-04-30 08:06:18 -0400
committerStefan Berger <stefanb@us.ibm.com>2010-04-30 08:06:18 -0400
commit59fe163f2ff0a7983a3c006e2454458c2432514e (patch)
tree75c8a08eb01d0e719ea726f3113ec7550ef03408
parentMAke virFileHasSuffix case insensitive (diff)
downloadlibvirt-59fe163f2ff0a7983a3c006e2454458c2432514e.tar.gz
libvirt-59fe163f2ff0a7983a3c006e2454458c2432514e.tar.bz2
libvirt-59fe163f2ff0a7983a3c006e2454458c2432514e.zip
Clean all tables before applying 'basic' rules
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.
-rw-r--r--src/conf/nwfilter_conf.h3
-rw-r--r--src/nwfilter/nwfilter_ebiptables_driver.c104
-rw-r--r--src/nwfilter/nwfilter_learnipaddr.c4
-rw-r--r--src/nwfilter/nwfilter_learnipaddr.h2
4 files changed, 96 insertions, 17 deletions
diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h
index d54f2ba05..3aef3fb11 100644
--- a/src/conf/nwfilter_conf.h
+++ b/src/conf/nwfilter_conf.h
@@ -521,6 +521,8 @@ typedef int (*virNWFilterApplyDHCPOnlyRules)(const char *ifname,
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;
};
diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c b/src/nwfilter/nwfilter_ebiptables_driver.c
index dcdd938a2..63bcbd740 100644
--- a/src/nwfilter/nwfilter_ebiptables_driver.c
+++ b/src/nwfilter/nwfilter_ebiptables_driver.c
@@ -102,6 +102,7 @@ static const char *m_physdev_out_str = "-m physdev " PHYSDEV_OUT;
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 *ifname,
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 *ifname,
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 *ifname,
return 0;
tear_down_tmpebchains:
- ebtablesRemoveBasicRules(ifname);
+ ebtablesCleanAll(ifname);
virNWFilterReportError(VIR_ERR_BUILD_FIREWALL,
"%s",
@@ -2782,12 +2779,7 @@ ebtablesApplyDHCPOnlyRules(const char *ifname,
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 *ifname,
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 *ifname,
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,
};
diff --git a/src/nwfilter/nwfilter_learnipaddr.c b/src/nwfilter/nwfilter_learnipaddr.c
index b63398e07..2bb777bad 100644
--- a/src/nwfilter/nwfilter_learnipaddr.c
+++ b/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));
diff --git a/src/nwfilter/nwfilter_learnipaddr.h b/src/nwfilter/nwfilter_learnipaddr.h
index 3594fc4e3..6f3cb7f20 100644
--- a/src/nwfilter/nwfilter_learnipaddr.h
+++ b/src/nwfilter/nwfilter_learnipaddr.h
@@ -60,7 +60,7 @@ int virNWFilterLearnIPAddress(virNWFilterTechDriverPtr techdriver,
enum howDetect howDetect);
virNWFilterIPAddrLearnReqPtr virNWFilterLookupLearnReq(int ifindex);
-
+int virNWFilterTerminateLearnReq(const char *ifname);
void virNWFilterDelIpAddrForIfname(const char *ifname);
const char *virNWFilterGetIpAddrForIfname(const char *ifname);