mirror of https://gitee.com/openkylin/libvirt.git
add MAC address based port filtering to qemu
* src/qemu/qemu.conf src/qemu/qemu_conf.c src/qemu/qemu_conf.h: there is a new config type option for mac filtering * src/qemu/qemu_bridge_filter.[ch]: new module for the ebtable entry points * src/qemu/qemu_driver.c: plug the MAC filtering at the right places in the domain life cycle * src/Makefile.am po/POTFILES.in: add the new module
This commit is contained in:
parent
1fc3816d0f
commit
0aa72ac6fd
|
@ -24,6 +24,7 @@ src/opennebula/one_driver.c
|
|||
src/openvz/openvz_conf.c
|
||||
src/openvz/openvz_driver.c
|
||||
src/phyp/phyp_driver.c
|
||||
src/qemu/qemu_bridge_filter.c
|
||||
src/qemu/qemu_conf.c
|
||||
src/qemu/qemu_driver.c
|
||||
src/qemu/qemu_monitor_text.c
|
||||
|
|
|
@ -185,7 +185,9 @@ QEMU_DRIVER_SOURCES = \
|
|||
qemu/qemu_conf.c qemu/qemu_conf.h \
|
||||
qemu/qemu_monitor_text.c \
|
||||
qemu/qemu_monitor_text.h \
|
||||
qemu/qemu_driver.c qemu/qemu_driver.h
|
||||
qemu/qemu_driver.c qemu/qemu_driver.h \
|
||||
qemu/qemu_bridge_filter.c \
|
||||
qemu/qemu_bridge_filter.h
|
||||
|
||||
UML_DRIVER_SOURCES = \
|
||||
uml/uml_conf.c uml/uml_conf.h \
|
||||
|
|
|
@ -152,3 +152,5 @@
|
|||
# in a location of $MOUNTPOINT/libvirt/qemu
|
||||
|
||||
# hugetlbfs_mount = "/dev/hugepages"
|
||||
|
||||
mac_filter = 1
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright (C) 2009 IBM Corp.
|
||||
* Copyright (C) 2007-2009 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors:
|
||||
* Gerhard Stenzel <gerhard.stenzel@de.ibm.com>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "ebtables.h"
|
||||
#include "qemu_conf.h"
|
||||
#include "qemu_driver.h"
|
||||
#include "util.h"
|
||||
#include "virterror_internal.h"
|
||||
#include "logging.h"
|
||||
|
||||
#include "qemu_bridge_filter.h"
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_QEMU
|
||||
|
||||
int
|
||||
networkAddEbtablesRules(struct qemud_driver *driver) {
|
||||
int err;
|
||||
|
||||
/* Set forward policy to DROP */
|
||||
if ((err = ebtablesAddForwardPolicyReject(driver->ebtables))) {
|
||||
virReportSystemError(NULL, err,
|
||||
_("failed to add ebtables rule to set default policy to drop on '%s'"),
|
||||
__FILE__);
|
||||
return err;
|
||||
}
|
||||
ebtablesSaveRules(driver->ebtables);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
networkDisableAllFrames(struct qemud_driver *driver) {
|
||||
int err;
|
||||
|
||||
/* add default rules */
|
||||
if ((err = networkAddEbtablesRules(driver))) {
|
||||
virReportSystemError(NULL, err,
|
||||
_("cannot filter mac addresses on bridge '%s'"),
|
||||
__FILE__);
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
networkAllowMacOnPort(virConnectPtr conn,
|
||||
struct qemud_driver *driver,
|
||||
const char * ifname,
|
||||
const unsigned char * mac) {
|
||||
|
||||
int err;
|
||||
|
||||
/* allow this combination of macaddr and ifname */
|
||||
ebtablesContext * ebtablescontext = driver->ebtables;
|
||||
if ((err = ebtablesAddForwardAllowIn(ebtablescontext,
|
||||
ifname,
|
||||
mac))) {
|
||||
virReportSystemError(conn, err,
|
||||
_("failed to add ebtables rule to allow routing to '%s'"),
|
||||
ifname);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
networkDisallowMacOnPort(virConnectPtr conn,
|
||||
struct qemud_driver *driver,
|
||||
const char * ifname,
|
||||
const unsigned char * mac) {
|
||||
|
||||
int err;
|
||||
|
||||
/* disallow this combination of macaddr and ifname */
|
||||
ebtablesContext * ebtablescontext = driver->ebtables;
|
||||
if ((err = ebtablesRemoveForwardAllowIn(ebtablescontext,
|
||||
ifname,
|
||||
mac))) {
|
||||
virReportSystemError(conn, err,
|
||||
_("failed to add ebtables rule to allow routing to '%s'"),
|
||||
ifname);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (C) 2009 IBM Corp.
|
||||
* Copyright (C) 2007-2009 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors:
|
||||
* Gerhard Stenzel <gerhard.stenzel@de.ibm.com>
|
||||
*/
|
||||
|
||||
#ifndef __QEMUD_BRIDGE_FILTER_H__
|
||||
#define __QEMUD_BRIDGE_FILTER_H__
|
||||
|
||||
|
||||
int networkAllowMacOnPort(virConnectPtr conn,
|
||||
struct qemud_driver *driver,
|
||||
const char * ifname,
|
||||
const unsigned char * mac);
|
||||
int networkDisallowMacOnPort(virConnectPtr conn,
|
||||
struct qemud_driver *driver,
|
||||
const char * ifname,
|
||||
const unsigned char * mac);
|
||||
int networkDisableAllFrames(struct qemud_driver *driver);
|
||||
int networkAddEbtablesRules(struct qemud_driver *driver);
|
||||
|
||||
|
||||
#endif /* __QEMUD_BRIDGE_FILTER_H__ */
|
|
@ -40,6 +40,7 @@
|
|||
#include "c-ctype.h"
|
||||
#include "virterror_internal.h"
|
||||
#include "qemu_conf.h"
|
||||
#include "qemu_bridge_filter.h"
|
||||
#include "uuid.h"
|
||||
#include "buf.h"
|
||||
#include "conf.h"
|
||||
|
@ -318,6 +319,24 @@ int qemudLoadDriverConfig(struct qemud_driver *driver,
|
|||
}
|
||||
}
|
||||
|
||||
p = virConfGetValue (conf, "mac_filter");
|
||||
CHECK_TYPE ("mac_filter", VIR_CONF_LONG);
|
||||
if (p) {
|
||||
driver->macFilter = p->l;
|
||||
if (!(driver->ebtables = ebtablesContextNew("qemu"))) {
|
||||
driver->macFilter = 0;
|
||||
virReportSystemError(NULL, errno,
|
||||
_("failed to enable mac filter in in '%s'"),
|
||||
__FILE__);
|
||||
}
|
||||
|
||||
if ((errno = networkDisableAllFrames(driver))) {
|
||||
virReportSystemError(NULL, errno,
|
||||
_("failed to add rule to drop all frames in '%s'"),
|
||||
__FILE__);
|
||||
}
|
||||
}
|
||||
|
||||
virConfFree (conf);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1194,6 +1213,14 @@ qemudNetworkIfaceConnect(virConnectPtr conn,
|
|||
tapfd = -1;
|
||||
}
|
||||
|
||||
if (driver->macFilter) {
|
||||
if ((err = networkAllowMacOnPort(conn, driver, net->ifname, net->mac))) {
|
||||
virReportSystemError(conn, err,
|
||||
_("failed to add ebtables rule to allow MAC address on '%s'"),
|
||||
net->ifname);
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(brname);
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include <config.h>
|
||||
|
||||
#include "ebtables.h"
|
||||
#include "internal.h"
|
||||
#include "bridge.h"
|
||||
#include "capabilities.h"
|
||||
|
@ -112,6 +113,9 @@ struct qemud_driver {
|
|||
char *hugetlbfs_mount;
|
||||
char *hugepage_path;
|
||||
|
||||
unsigned int macFilter : 1;
|
||||
ebtablesContext *ebtables;
|
||||
|
||||
virCapsPtr caps;
|
||||
|
||||
/* An array of callbacks */
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#include "qemu_driver.h"
|
||||
#include "qemu_conf.h"
|
||||
#include "qemu_monitor_text.h"
|
||||
#include "qemu_bridge_filter.h"
|
||||
#include "c-ctype.h"
|
||||
#include "event.h"
|
||||
#include "buf.h"
|
||||
|
@ -2170,6 +2171,22 @@ static void qemudShutdownVMDaemon(virConnectPtr conn,
|
|||
|
||||
VIR_DEBUG(_("Shutting down VM '%s'\n"), vm->def->name);
|
||||
|
||||
if (driver->macFilter) {
|
||||
int i;
|
||||
virDomainDefPtr def = vm->def;
|
||||
for (i = 0 ; i < def->nnets ; i++) {
|
||||
virDomainNetDefPtr net = def->nets[i];
|
||||
if (net->ifname == NULL)
|
||||
continue;
|
||||
if ((errno = networkDisallowMacOnPort(conn, driver, net->ifname,
|
||||
net->mac))) {
|
||||
virReportSystemError(conn, errno,
|
||||
_("failed to remove ebtables rule to allow MAC address on '%s'"),
|
||||
net->ifname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (virKillProcess(vm->pid, 0) == 0 &&
|
||||
virKillProcess(vm->pid, SIGTERM) < 0)
|
||||
virReportSystemError(conn, errno,
|
||||
|
|
Loading…
Reference in New Issue