[libvirt] [RFC] Proposal for introduction of network traffic filtering capabilities for filtering of network traffic from and to VMs
by Stefan Berger
Hello!
The following is a proposal to introduce network traffic filtering
capabilities for the network traffic originating from and destined to
virtual machines. Libvirt's capabilities will be extended to allow users
to describe what traffic filtering rules are to be applied on a virtual
machine (using XML) and libvirt then creates the appropriate ebtables and
iptables rules and applies those on the host when the virtual machine
starts up, resumes after suspension or resumes on a new host after
migration. libvirt tears down the traffic filtering rules when the virtual
machine shuts down, suspends, or a VM is migrated to another host. It will
also be possible to modify the filtering rules while a virtual machine is
running. In this architecture we apply the firewall rules on the outside
of the virtual machines on the Linux host and make use of the fact that
virtual machines can be configured by libvirt to have their network
traffic pass through the host and the host exposes (tap) 'backend'
interfaces on which the firewall rules can be applied. The application of
the firewall rules is optional and those who do not want to introduce a
raw network throughput performance hit on their system due to the
evaluation of every packet passing through the filtering chains, do not
have to use these capabilities. An initial implementation would be done
for libvirt's Qemu support.
As stated above, the application of firewall rules on virtual machines
will require some form of XML description that lets the user choose what
type of filtering is to be performed. In effect the user needs to be able
to tell libvirt which ebtables and iptables rules to generate so that the
appropriate filtering can be done. We realize that ebtables and iptables
have lots of capabilities but think that we need to restrict which
capabilities can actually be 'reached' through this XML.
The following proposal is based on an XML as defined by the DMTF (
http://www.dmtf.org/standards/cim/cim_schema_v2230/CIM_Network.pdf, slide
10) with extensions for processing of ARP packets.It gives control over
the evaluation of Ethernet (MAC) frames, ARP packet data and IP header
information. A (draft) XML skeleton in this case could look as follows:
<FilterEntry>
<Action>DROP|ACCEPT</Action> <!-- from FilterEntry -->
<TrafficType>incoming [to VM]|outgoing [from VM]</TrafficType>
<Hdr8021Filter>
<HdrSrcMACAddr8021> </HdrSrcMACAddr8021>
<HdrSrcMACMask8021> </HdrSrcMACMask8021>
<HdrDestMACAddr8021> </HdrDestMACAddr8021>
<HdrDestMACMask8021> </HdrDestMACMask8021>
<HdrProtocolID8021> numeric and/or string?
</HdrProtocolID8021>
<HdrPriorityValue8021></HdrPriorityValue8021>
<HdrVLANID8021> </HdrVLANID8021>
</Hdr8021Filter>
<ARPFilter>
<HWType> </HWType>
<ProtocolType> </ProtocolType>
<OPCode> </OPCode>
<SrcMACAddr> </SrcMACAddr>
<SrcIPAddr> </SrcIPAddr>
<DestMACAddr> </DestMACAddr>
<DestIPAddr> </DestIPAddr>
</ARPFilter>
<IPHeadersFilter>
<HdrIPVersion> </HdrIPVersion>
<HdrSrcAddress> </HdrSrcAddress>
<HdrSrcMask> </HdrSrcMask>
<HdrDestAddress> </HdrDestAddress>
<HdrDestMask> </HdrDestMask>
<HdrProtocolID> numeric and/or string? </HdrProtocolID>
<HdrSrcPortStart> </HdrSrcPortStart>
<HdrSrcPortEnd> </HdrSrcPortEnd>
<HdrDestPortStart> </HdrDestPortStart>
<HdrDestPortEnd> </HdrDestPortEnd>
<HdrDSCP> </HdrDSCP>
</IPHeadersFilter>
</FilterEntry>
Since the ebtables and iptables command cannot accept all possible
parameters at the same time, only a certain subset of the above parameters
may be set for any given filter command. Higher level application writers
will likely use a library that lets them choose which features they would
want to have enforced, such as no-broadcast or no-multicast, enforcement
of MAC spoofing prevention or ARP poisoning prevention, which then
generates this lower level XML rules in the appropriate order of the
rules.
Further, we will introduce filter pools where a collection of the above
filter rules can be stored and referenced to by virtual machines'
individual interface. A reference to such a filter pool entry will be
given in the interface description and may look as in the following draft
XML:
<interface type='bridge'>
<source bridge='virbr0'/>
<script path='vif-bridge'/>
<firewall>
<reference profile='generic-layer2' ip_address='10.0.0.1'/>
<reference profile='VM-specific-layer3'/>
</firewall>
</interface>
The above XML has one reference to a generic layer2 filter template XML
that should be usable by multiple virtual machines but would need to be
customized with interface-specific parameters. In this case, the IP
address of the interface is explicitly provided in order to make the
filter XML template a concrete XML for the particular interface. The MAC
address of the interface is not explicitly provided since it will already
have been randomly generated by libvirt at the point when this layer2
filter XML needs to be converted into concrete ebtables commands/rules. We
still need to determine how the format of a template should look like,
though an idea would be to indicate a placeholder for a VM's MAC address
using THIS_MAC and similarly for the IP address with THIS_IP as
placeholder.
Further, we would introduce the management of filter 'pools'. Considering
existing functionality in libvirt and CLI commands for similar type of
management functionality, the following CLI commands would be added:
virsh nwfilter-create <file>
virsh nwfilter-destroy <profile name>
virsh nwfilter-list <options>
virsh nwfilter-dumpxml <profile name>
virsh nwfilter-update <filename> (performs an update on an existing
profile replacing all rules)
possibly also:
virsh nwfilter-edit <profile name>
virsh nwfilter-create-from <profile name>
Please let us know what you think of this proposal.
Regards
Stefan, Gerhard and Vivek
14 years, 9 months
[libvirt] [PATCH] qemu: avoid null dereference on failed migration
by Eric Blake
From: Eric Blake <eblake(a)redhat.com>
* src/qemu/qemu_monitor_text.c
(qemuMonitorTextGetMigrationStatus): Check for failed strchr, to
silence a coverity warning.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
src/qemu/qemu_monitor_text.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index 62ffcc6..e7b4b1f 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -989,6 +989,11 @@ int qemuMonitorTextGetMigrationStatus(qemuMonitorPtr mon,
if ((tmp = strstr(reply, MIGRATION_PREFIX)) != NULL) {
tmp += strlen(MIGRATION_PREFIX);
end = strchr(tmp, '\r');
+ if (end == NULL) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unexpected migration status in %s"), reply);
+ goto cleanup;
+ }
*end = '\0';
if ((*status = qemuMonitorMigrationStatusTypeFromString(tmp)) < 0) {
--
1.6.6.1
14 years, 9 months
[libvirt] [PATCH] Do not search xenstore for disk device IDs
by Jim Fehlig
Disk devices can be referenced by name in Xen, e.g. when modifying
their configuration or remvoving them. As such, don't search
xenstore for a device ID corresponding to the disk device. Instead,
search the disks contained in the domain definition and use the
disk's target name if found.
This approach allows removing a disk when domain is inactive. We
obviously can't search xenstore when the domain is inactive.
---
src/xen/xend_internal.c | 38 +++++++++++++++++++++++---------------
1 files changed, 23 insertions(+), 15 deletions(-)
diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
index 9d95291..d0d32e2 100644
--- a/src/xen/xend_internal.c
+++ b/src/xen/xend_internal.c
@@ -93,6 +93,7 @@ xenDaemonFormatSxprOnePCI(virConnectPtr conn,
static int
virDomainXMLDevID(virDomainPtr domain,
+ virDomainDefPtr domDef,
virDomainDeviceDefPtr dev,
char *class,
char *ref,
@@ -4212,7 +4213,7 @@ xenDaemonAttachDeviceFlags(virDomainPtr domain, const char *xml,
sexpr = virBufferContentAndReset(&buf);
- if (virDomainXMLDevID(domain, dev, class, ref, sizeof(ref))) {
+ if (virDomainXMLDevID(domain, def, dev, class, ref, sizeof(ref))) {
/* device doesn't exist, define it */
ret = xend_op(domain->conn, domain->name, "op", "device_create",
"config", sexpr, NULL);
@@ -4306,7 +4307,7 @@ xenDaemonDetachDeviceFlags(virDomainPtr domain, const char *xml,
def, xml, VIR_DOMAIN_XML_INACTIVE)))
goto cleanup;
- if (virDomainXMLDevID(domain, dev, class, ref, sizeof(ref)))
+ if (virDomainXMLDevID(domain, def, dev, class, ref, sizeof(ref)))
goto cleanup;
if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) {
@@ -6048,6 +6049,7 @@ error:
*/
static int
virDomainXMLDevID(virDomainPtr domain,
+ virDomainDefPtr domDef,
virDomainDeviceDefPtr dev,
char *class,
char *ref,
@@ -6056,27 +6058,33 @@ virDomainXMLDevID(virDomainPtr domain,
xenUnifiedPrivatePtr priv = domain->conn->privateData;
char *xref;
char *tmp;
+ unsigned int i;
+ virDomainDiskDefPtr disk;
if (dev->type == VIR_DOMAIN_DEVICE_DISK) {
+ if (dev->data.disk->dst == NULL)
+ return -1;
if (dev->data.disk->driverName &&
STREQ(dev->data.disk->driverName, "tap"))
strcpy(class, "tap");
else
strcpy(class, "vbd");
- if (dev->data.disk->dst == NULL)
- return -1;
- xenUnifiedLock(priv);
- xref = xenStoreDomainGetDiskID(domain->conn, domain->id,
- dev->data.disk->dst);
- xenUnifiedUnlock(priv);
- if (xref == NULL)
- return -1;
-
- tmp = virStrcpy(ref, xref, ref_len);
- VIR_FREE(xref);
- if (tmp == NULL)
- return -1;
+ /* For disks, the device name can be used directly.
+ * If disk device exists in domain definintion,
+ * copy it to ref and return success.
+ */
+ for (i = 0; i < domDef->ndisks; i++) {
+ disk = domDef->disks[i];
+ if (STREQ(dev->data.disk->dst, disk->dst)) {
+ tmp = virStrcpy(ref, disk->dst, ref_len);
+ if (tmp == NULL)
+ return -1;
+ else
+ return 0;
+ }
+ }
+ return -1;
} else if (dev->type == VIR_DOMAIN_DEVICE_NET) {
char mac[30];
virDomainNetDefPtr def = dev->data.net;
--
1.6.0.2
14 years, 9 months
[libvirt] (no subject)
by Daniel P. Berrange
Repost of
http://www.redhat.com/archives/libvir-list/2010-February/msg00177.html
The virsh output is now scaled to show KB/MB as needed, instead of
always bytes.
The public API gained extra status
VIR_DOMAIN_JOB_COMPLETED = 3, /* Job has finished, but isn't cleaned up */
VIR_DOMAIN_JOB_FAILED = 4, /* Job hit error, but isn't cleaned up */
VIR_DOMAIN_JOB_CANCELLED = 6, /* Job was aborted, but isn't cleaned up */
to allow to more easily detecting end of a job, once we allow
for truely async usage
14 years, 9 months
[libvirt] Hypervisor raw options
by Daniel Dehennin
Hello,
I wonder if it's possible to add hypervisor pass-through options, I add
some usage of kvm -startdate and need to use a script which call kvm
with the desired option.
Something like:
<emulator>/usr/bin/kvm</emulator>
<emulator-options>
<option>-option1</option>
<option>-option2</option>
</emulator-options>
The several <option/> will be passed to the <emulator/> command.
Regards.
--
Daniel Dehennin
Récupérer ma clef GPG:
gpg --keyserver pgp.mit.edu --recv-keys 0x6A2540D1
14 years, 9 months
[libvirt] [PATCH] build: avoid warning about unused variables
by Jim Meyering
>From 8ddff3e6cdccc2b4289509c6941b43f2ddf8e643 Mon Sep 17 00:00:00 2001
From: Jim Meyering <meyering(a)redhat.com>
Date: Thu, 25 Feb 2010 14:19:33 +0100
Subject: [PATCH] build: avoid warning about unused variables
* tools/virsh.c (cmdCPUBaseline): Remove declarations of unused
variables, p and cur.
---
tools/virsh.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index 5fdbbe5..89eefcf 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -7048,12 +7048,11 @@ cmdCPUBaseline(vshControl *ctl, const vshCmd *cmd)
int found;
int ret = TRUE;
char *buffer;
- char *p;
char *result = NULL;
const char **list = NULL;
unsigned int count = 0;
xmlDocPtr doc = NULL;
- xmlNodePtr node_list, cur;
+ xmlNodePtr node_list;
xmlXPathContextPtr ctxt = NULL;
xmlSaveCtxtPtr sctxt = NULL;
xmlBufferPtr buf = NULL;
--
1.7.0.401.g84adb
14 years, 9 months
[libvirt] [PATCH] libvirtd: do not ignore failure to set group ID in privileged mode
by Jim Meyering
Coverity spotted these unchecked setgid calls:
>From 7eddaf457d54974859a8c22cced6f43e2d267746 Mon Sep 17 00:00:00 2001
From: Jim Meyering <meyering(a)redhat.com>
Date: Fri, 26 Feb 2010 10:42:14 +0100
Subject: [PATCH] libvirtd: do not ignore failure to set group ID in privileged mode
* daemon/libvirtd.c (qemudListenUnix): Diagnose and fail upon
failure to set or restore group-ID.
---
daemon/libvirtd.c | 12 ++++++++----
1 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index cee6f13..9bdbecb 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -560,8 +560,10 @@ static int qemudListenUnix(struct qemud_server *server,
oldgrp = getgid();
oldmask = umask(readonly ? ~unix_sock_ro_mask : ~unix_sock_rw_mask);
- if (server->privileged)
- setgid(unix_sock_gid);
+ if (server->privileged && setgid(unix_sock_gid)) {
+ VIR_ERROR(_("Failed to set group ID to %d"), unix_sock_gid);
+ goto cleanup;
+ }
if (bind(sock->fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
VIR_ERROR(_("Failed to bind socket to '%s': %s"),
@@ -569,8 +571,10 @@ static int qemudListenUnix(struct qemud_server *server,
goto cleanup;
}
umask(oldmask);
- if (server->privileged)
- setgid(oldgrp);
+ if (server->privileged && setgid(oldgrp)) {
+ VIR_ERROR(_("Failed to restore group ID to %d"), oldgrp);
+ goto cleanup;
+ }
if (listen(sock->fd, 30) < 0) {
VIR_ERROR(_("Failed to listen for connections on '%s': %s"),
--
1.7.0.442.g55ad1
14 years, 10 months
[libvirt] [PATCH] build: avoid warning about return-with-value in void function
by Jim Meyering
I saw this:
virsh.c: In function 'virshReportError':
virsh.c:363: warning: 'return' with a value, in function returning void
>From fc83f08ac204cec5fba474a23bd19386d1a415d7 Mon Sep 17 00:00:00 2001
From: Jim Meyering <meyering(a)redhat.com>
Date: Fri, 26 Feb 2010 11:50:34 +0100
Subject: [PATCH] build: avoid warning about return-with-value in void function
* tools/virsh.c: Just "return;", not "return NULL;".
---
tools/virsh.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index f7fd7d4..3b1011c 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -360,7 +360,7 @@ virshReportError(vshControl *ctl)
* no error was ever raised, so just ignore */
last_error = virSaveLastError();
if (!last_error || last_error->code == VIR_ERR_OK)
- return NULL;
+ return;
}
if (last_error->code == VIR_ERR_OK) {
--
1.7.0.442.g55ad1
14 years, 10 months