mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
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_conf.c
|
||||||
src/openvz/openvz_driver.c
|
src/openvz/openvz_driver.c
|
||||||
src/phyp/phyp_driver.c
|
src/phyp/phyp_driver.c
|
||||||
|
src/qemu/qemu_bridge_filter.c
|
||||||
src/qemu/qemu_conf.c
|
src/qemu/qemu_conf.c
|
||||||
src/qemu/qemu_driver.c
|
src/qemu/qemu_driver.c
|
||||||
src/qemu/qemu_monitor_text.c
|
src/qemu/qemu_monitor_text.c
|
||||||
|
@ -185,7 +185,9 @@ QEMU_DRIVER_SOURCES = \
|
|||||||
qemu/qemu_conf.c qemu/qemu_conf.h \
|
qemu/qemu_conf.c qemu/qemu_conf.h \
|
||||||
qemu/qemu_monitor_text.c \
|
qemu/qemu_monitor_text.c \
|
||||||
qemu/qemu_monitor_text.h \
|
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_DRIVER_SOURCES = \
|
||||||
uml/uml_conf.c uml/uml_conf.h \
|
uml/uml_conf.c uml/uml_conf.h \
|
||||||
|
@ -152,3 +152,5 @@
|
|||||||
# in a location of $MOUNTPOINT/libvirt/qemu
|
# in a location of $MOUNTPOINT/libvirt/qemu
|
||||||
|
|
||||||
# hugetlbfs_mount = "/dev/hugepages"
|
# hugetlbfs_mount = "/dev/hugepages"
|
||||||
|
|
||||||
|
mac_filter = 1
|
||||||
|
108
src/qemu/qemu_bridge_filter.c
Normal file
108
src/qemu/qemu_bridge_filter.c
Normal file
@ -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;
|
||||||
|
}
|
39
src/qemu/qemu_bridge_filter.h
Normal file
39
src/qemu/qemu_bridge_filter.h
Normal file
@ -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 "c-ctype.h"
|
||||||
#include "virterror_internal.h"
|
#include "virterror_internal.h"
|
||||||
#include "qemu_conf.h"
|
#include "qemu_conf.h"
|
||||||
|
#include "qemu_bridge_filter.h"
|
||||||
#include "uuid.h"
|
#include "uuid.h"
|
||||||
#include "buf.h"
|
#include "buf.h"
|
||||||
#include "conf.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);
|
virConfFree (conf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1194,6 +1213,14 @@ qemudNetworkIfaceConnect(virConnectPtr conn,
|
|||||||
tapfd = -1;
|
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:
|
cleanup:
|
||||||
VIR_FREE(brname);
|
VIR_FREE(brname);
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
|
#include "ebtables.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "bridge.h"
|
#include "bridge.h"
|
||||||
#include "capabilities.h"
|
#include "capabilities.h"
|
||||||
@ -112,6 +113,9 @@ struct qemud_driver {
|
|||||||
char *hugetlbfs_mount;
|
char *hugetlbfs_mount;
|
||||||
char *hugepage_path;
|
char *hugepage_path;
|
||||||
|
|
||||||
|
unsigned int macFilter : 1;
|
||||||
|
ebtablesContext *ebtables;
|
||||||
|
|
||||||
virCapsPtr caps;
|
virCapsPtr caps;
|
||||||
|
|
||||||
/* An array of callbacks */
|
/* An array of callbacks */
|
||||||
|
@ -56,6 +56,7 @@
|
|||||||
#include "qemu_driver.h"
|
#include "qemu_driver.h"
|
||||||
#include "qemu_conf.h"
|
#include "qemu_conf.h"
|
||||||
#include "qemu_monitor_text.h"
|
#include "qemu_monitor_text.h"
|
||||||
|
#include "qemu_bridge_filter.h"
|
||||||
#include "c-ctype.h"
|
#include "c-ctype.h"
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
#include "buf.h"
|
#include "buf.h"
|
||||||
@ -2170,6 +2171,22 @@ static void qemudShutdownVMDaemon(virConnectPtr conn,
|
|||||||
|
|
||||||
VIR_DEBUG(_("Shutting down VM '%s'\n"), vm->def->name);
|
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 &&
|
if (virKillProcess(vm->pid, 0) == 0 &&
|
||||||
virKillProcess(vm->pid, SIGTERM) < 0)
|
virKillProcess(vm->pid, SIGTERM) < 0)
|
||||||
virReportSystemError(conn, errno,
|
virReportSystemError(conn, errno,
|
||||||
|
Loading…
Reference in New Issue
Block a user