mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-27 19:11:16 +00:00
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.
This commit is contained in:
parent
b9efc7dc3b
commit
59fe163f2f
@ -521,6 +521,8 @@ typedef int (*virNWFilterApplyDHCPOnlyRules)(const char *ifname,
|
|||||||
|
|
||||||
typedef int (*virNWFilterRemoveBasicRules)(const char *ifname);
|
typedef int (*virNWFilterRemoveBasicRules)(const char *ifname);
|
||||||
|
|
||||||
|
typedef int (*virNWFilterDropAllRules)(const char *ifname);
|
||||||
|
|
||||||
enum techDrvFlags {
|
enum techDrvFlags {
|
||||||
TECHDRV_FLAG_INITIALIZED = (1 << 0),
|
TECHDRV_FLAG_INITIALIZED = (1 << 0),
|
||||||
};
|
};
|
||||||
@ -544,6 +546,7 @@ struct _virNWFilterTechDriver {
|
|||||||
virNWFilterCanApplyBasicRules canApplyBasicRules;
|
virNWFilterCanApplyBasicRules canApplyBasicRules;
|
||||||
virNWFilterApplyBasicRules applyBasicRules;
|
virNWFilterApplyBasicRules applyBasicRules;
|
||||||
virNWFilterApplyDHCPOnlyRules applyDHCPOnlyRules;
|
virNWFilterApplyDHCPOnlyRules applyDHCPOnlyRules;
|
||||||
|
virNWFilterDropAllRules applyDropAllRules;
|
||||||
virNWFilterRemoveBasicRules removeBasicRules;
|
virNWFilterRemoveBasicRules removeBasicRules;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -102,6 +102,7 @@ static const char *m_physdev_out_str = "-m physdev " PHYSDEV_OUT;
|
|||||||
static int ebtablesRemoveBasicRules(const char *ifname);
|
static int ebtablesRemoveBasicRules(const char *ifname);
|
||||||
static int ebiptablesDriverInit(void);
|
static int ebiptablesDriverInit(void);
|
||||||
static void ebiptablesDriverShutdown(void);
|
static void ebiptablesDriverShutdown(void);
|
||||||
|
static int ebtablesCleanAll(const char *ifname);
|
||||||
|
|
||||||
|
|
||||||
struct ushort_map {
|
struct ushort_map {
|
||||||
@ -2679,12 +2680,7 @@ ebtablesApplyBasicRules(const char *ifname,
|
|||||||
|
|
||||||
virFormatMacAddr(macaddr, macaddr_str);
|
virFormatMacAddr(macaddr, macaddr_str);
|
||||||
|
|
||||||
ebtablesUnlinkTmpRootChain(&buf, 1, ifname);
|
ebtablesCleanAll(ifname);
|
||||||
ebtablesUnlinkTmpRootChain(&buf, 0, ifname);
|
|
||||||
ebtablesRemoveTmpSubChains(&buf, ifname);
|
|
||||||
ebtablesRemoveTmpRootChain(&buf, 1, ifname);
|
|
||||||
ebtablesRemoveTmpRootChain(&buf, 0, ifname);
|
|
||||||
ebiptablesExecCLI(&buf, &cli_status);
|
|
||||||
|
|
||||||
ebtablesCreateTmpRootChain(&buf, 1, ifname, 1);
|
ebtablesCreateTmpRootChain(&buf, 1, ifname, 1);
|
||||||
|
|
||||||
@ -2723,6 +2719,7 @@ ebtablesApplyBasicRules(const char *ifname,
|
|||||||
CMD_STOPONERR(1));
|
CMD_STOPONERR(1));
|
||||||
|
|
||||||
ebtablesLinkTmpRootChain(&buf, 1, ifname, 1);
|
ebtablesLinkTmpRootChain(&buf, 1, ifname, 1);
|
||||||
|
ebtablesRenameTmpRootChain(&buf, 1, ifname);
|
||||||
|
|
||||||
if (ebiptablesExecCLI(&buf, &cli_status) || cli_status != 0)
|
if (ebiptablesExecCLI(&buf, &cli_status) || cli_status != 0)
|
||||||
goto tear_down_tmpebchains;
|
goto tear_down_tmpebchains;
|
||||||
@ -2730,7 +2727,7 @@ ebtablesApplyBasicRules(const char *ifname,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
tear_down_tmpebchains:
|
tear_down_tmpebchains:
|
||||||
ebtablesRemoveBasicRules(ifname);
|
ebtablesCleanAll(ifname);
|
||||||
|
|
||||||
virNWFilterReportError(VIR_ERR_BUILD_FIREWALL,
|
virNWFilterReportError(VIR_ERR_BUILD_FIREWALL,
|
||||||
"%s",
|
"%s",
|
||||||
@ -2782,12 +2779,7 @@ ebtablesApplyDHCPOnlyRules(const char *ifname,
|
|||||||
|
|
||||||
virFormatMacAddr(macaddr, macaddr_str);
|
virFormatMacAddr(macaddr, macaddr_str);
|
||||||
|
|
||||||
ebtablesUnlinkTmpRootChain(&buf, 1, ifname);
|
ebtablesCleanAll(ifname);
|
||||||
ebtablesUnlinkTmpRootChain(&buf, 0, ifname);
|
|
||||||
ebtablesRemoveTmpSubChains(&buf, ifname);
|
|
||||||
ebtablesRemoveTmpRootChain(&buf, 1, ifname);
|
|
||||||
ebtablesRemoveTmpRootChain(&buf, 0, ifname);
|
|
||||||
ebiptablesExecCLI(&buf, &cli_status);
|
|
||||||
|
|
||||||
ebtablesCreateTmpRootChain(&buf, 1, ifname, 1);
|
ebtablesCreateTmpRootChain(&buf, 1, ifname, 1);
|
||||||
ebtablesCreateTmpRootChain(&buf, 0, ifname, 1);
|
ebtablesCreateTmpRootChain(&buf, 0, ifname, 1);
|
||||||
@ -2842,6 +2834,8 @@ ebtablesApplyDHCPOnlyRules(const char *ifname,
|
|||||||
|
|
||||||
ebtablesLinkTmpRootChain(&buf, 1, ifname, 1);
|
ebtablesLinkTmpRootChain(&buf, 1, ifname, 1);
|
||||||
ebtablesLinkTmpRootChain(&buf, 0, ifname, 1);
|
ebtablesLinkTmpRootChain(&buf, 0, ifname, 1);
|
||||||
|
ebtablesRenameTmpRootChain(&buf, 1, ifname);
|
||||||
|
ebtablesRenameTmpRootChain(&buf, 0, ifname);
|
||||||
|
|
||||||
if (ebiptablesExecCLI(&buf, &cli_status) || cli_status != 0)
|
if (ebiptablesExecCLI(&buf, &cli_status) || cli_status != 0)
|
||||||
goto tear_down_tmpebchains;
|
goto tear_down_tmpebchains;
|
||||||
@ -2851,7 +2845,7 @@ ebtablesApplyDHCPOnlyRules(const char *ifname,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
tear_down_tmpebchains:
|
tear_down_tmpebchains:
|
||||||
ebtablesRemoveBasicRules(ifname);
|
ebtablesCleanAll(ifname);
|
||||||
|
|
||||||
virNWFilterReportError(VIR_ERR_BUILD_FIREWALL,
|
virNWFilterReportError(VIR_ERR_BUILD_FIREWALL,
|
||||||
"%s",
|
"%s",
|
||||||
@ -2863,8 +2857,83 @@ 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
|
static int
|
||||||
ebtablesRemoveBasicRules(const char *ifname)
|
ebtablesRemoveBasicRules(const char *ifname)
|
||||||
|
{
|
||||||
|
return ebtablesCleanAll(ifname);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int ebtablesCleanAll(const char *ifname)
|
||||||
{
|
{
|
||||||
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
||||||
int cli_status;
|
int cli_status;
|
||||||
@ -2872,6 +2941,12 @@ ebtablesRemoveBasicRules(const char *ifname)
|
|||||||
if (!ebtables_cmd_path)
|
if (!ebtables_cmd_path)
|
||||||
return 0;
|
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, 1, ifname);
|
||||||
ebtablesUnlinkTmpRootChain(&buf, 0, ifname);
|
ebtablesUnlinkTmpRootChain(&buf, 0, ifname);
|
||||||
ebtablesRemoveTmpSubChains(&buf, ifname);
|
ebtablesRemoveTmpSubChains(&buf, ifname);
|
||||||
@ -3265,6 +3340,7 @@ virNWFilterTechDriver ebiptables_driver = {
|
|||||||
.canApplyBasicRules = ebiptablesCanApplyBasicRules,
|
.canApplyBasicRules = ebiptablesCanApplyBasicRules,
|
||||||
.applyBasicRules = ebtablesApplyBasicRules,
|
.applyBasicRules = ebtablesApplyBasicRules,
|
||||||
.applyDHCPOnlyRules = ebtablesApplyDHCPOnlyRules,
|
.applyDHCPOnlyRules = ebtablesApplyDHCPOnlyRules,
|
||||||
|
.applyDropAllRules = ebtablesApplyDropAllRules,
|
||||||
.removeBasicRules = ebtablesRemoveBasicRules,
|
.removeBasicRules = ebtablesRemoveBasicRules,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -598,8 +598,6 @@ learnIPAddressThread(void *arg)
|
|||||||
if (handle)
|
if (handle)
|
||||||
pcap_close(handle);
|
pcap_close(handle);
|
||||||
|
|
||||||
techdriver->removeBasicRules(req->ifname);
|
|
||||||
|
|
||||||
if (req->status == 0) {
|
if (req->status == 0) {
|
||||||
int ret;
|
int ret;
|
||||||
char inetaddr[INET_ADDRSTRLEN];
|
char inetaddr[INET_ADDRSTRLEN];
|
||||||
@ -624,6 +622,8 @@ learnIPAddressThread(void *arg)
|
|||||||
_("encountered an error on interface %s "
|
_("encountered an error on interface %s "
|
||||||
"index %d"),
|
"index %d"),
|
||||||
req->ifname, req->ifindex);
|
req->ifname, req->ifindex);
|
||||||
|
|
||||||
|
techdriver->applyDropAllRules(req->ifname);
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&req->thread, 0x0, sizeof(req->thread));
|
memset(&req->thread, 0x0, sizeof(req->thread));
|
||||||
|
@ -60,7 +60,7 @@ int virNWFilterLearnIPAddress(virNWFilterTechDriverPtr techdriver,
|
|||||||
enum howDetect howDetect);
|
enum howDetect howDetect);
|
||||||
|
|
||||||
virNWFilterIPAddrLearnReqPtr virNWFilterLookupLearnReq(int ifindex);
|
virNWFilterIPAddrLearnReqPtr virNWFilterLookupLearnReq(int ifindex);
|
||||||
|
int virNWFilterTerminateLearnReq(const char *ifname);
|
||||||
|
|
||||||
void virNWFilterDelIpAddrForIfname(const char *ifname);
|
void virNWFilterDelIpAddrForIfname(const char *ifname);
|
||||||
const char *virNWFilterGetIpAddrForIfname(const char *ifname);
|
const char *virNWFilterGetIpAddrForIfname(const char *ifname);
|
||||||
|
Loading…
Reference in New Issue
Block a user