Commit Graph

62 Commits

Author SHA1 Message Date
Daniel P. Berrange
a8ae7d19f4 Remove all use of inet_pton and inet_ntop
The  inet_pton and inet_ntop functions are obsolete, replaced
by getaddrinfo+getnameinfo with the AI_NUMERICHOST flag set.
These can be accessed via the virSocket APIs.

The bridge.c code had methods for fetching the IP address of
a bridge which used inet_ntop. Aside from the use of inet_ntop
these methods are broken, because a NIC can have multiple
addresses and this only returns one address. Since the methods
are never used, just remove them.

* src/conf/network_conf.c, src/nwfilter/nwfilter_learnipaddr.c:
  Replace inet_pton and inet_ntop with virSocket APIs
* src/util/bridge.c, src/util/bridge.h: Remove unused methods
  which called inet_ntop.
2010-10-22 11:59:18 +01:00
Daniel P. Berrange
497adba2d4 Expand virSocketFormat to be more flexible
The getnameinfo() function is more flexible than inet_ntop()
avoiding the need to if/else the code based on socket family.
Also make it support UNIX socket addrs and allow inclusion
of a port (service) address. Finally do proper error reporting
via normal APIs.

* src/conf/domain_conf.c, src/nwfilter/nwfilter_ebiptables_driver.c,
  src/qemu/qemu_conf.c: Fix error handling with virSocketFormat
* src/util/network.c: Rewrite virSocketFormat to use getnameinfo
  and cope with UNIX socket addrs.
2010-10-22 11:24:12 +01:00
Daniel P. Berrange
7ab7d17bfb Remove pointless nwIPAddress struct & void *casts
The nwIPAddress was simply a wrapper about virSocketAddr.
Just use the latter directly, removing all the extra field
de-references from code & helper APIs for parsing/formatting.

Also remove all the redundant casts from strong types to
void * and then immediately back to strong types.

* src/conf/nwfilter_conf.h: Remove nwIPAddress
* src/conf/nwfilter_conf.c, src/nwfilter/nwfilter_ebiptables_driver.c:
  Update to use virSocketAddr and remove void * casts.
2010-10-22 11:21:27 +01:00
Stefan Berger
c2fbdf1088 nwfilter: avoid dir. enforcement for certain types of rules
Avoid the enforcement of direction if
- icmp rules specify the type/code information
- the 'skipMatch' variable is set to 'true'
2010-10-19 19:25:37 -04:00
Stefan Berger
7d79da247a nwfilter: changes to rules in VM->host table
In the table built for traffic coming from the VM going to the host make the following changes:

- don't ACCEPT the packets but do a 'RETURN' and let the host-specific firewall rules in subsequent rules evaluate whether the traffic is allowed to enter

- use the '-m state' in the rules as everywhere else
2010-10-19 11:35:58 -04:00
Stefan Berger
2b3df906f3 nwfilter: cut off connections after changing filters
The following filter transition from a filter allowing incoming TCP connections

  <rule action='accept' direction='in' priority='401'>
    <tcp/>
  </rule>
  <rule action='accept' direction='out' priority='500'>
    <tcp/>
  </rule>

to one that does not allow them

  <rule action='drop' direction='in' priority='401'>
    <tcp/>
  </rule>
  <rule action='accept' direction='out' priority='500'>
    <tcp/>
  </rule>

did previously not cut off existing (ssh) connections but only prevented newly initiated ones. The attached patch allows to cut off existing connections as well, thus enforcing what the filter is showing.

I had only tested with a configuration where the physical interface is connected to the bridge where the filters are applied. This patch now also solves a filtering problem where the physical interface is not connected to the bridge, but the bridge is given an IP address and the host routes between bridge and physical interface. Here the filters drop non-allowed traffic on the outgoing side on the host.
2010-10-14 08:54:03 -04:00
Stefan Berger
4435f3c477 nwfilter: resolve deadlock between VM ops and filter update
This is from a bug report and conversation on IRC where Soren reported that while a filter update is occurring on one or more VMs (due to a rule having been edited for example), a deadlock can occur when a VM referencing a filter is started.

The problem is caused by the two locking sequences of

qemu driver, qemu domain, filter             # for the VM start operation
filter, qemu_driver, qemu_domain            # for the filter update operation

that obviously don't lock in the same order. The problem is the 2nd lock sequence. Here the qemu_driver lock is being grabbed in qemu_driver:qemudVMFilterRebuild()

The following solution is based on the idea of trying to re-arrange the 2nd sequence of locks as follows:

qemu_driver, filter, qemu_driver, qemu_domain

and making the qemu driver recursively lockable so that a second lock can occur, this would then lead to the following net-locking sequence

qemu_driver, filter, qemu_domain

where the 2nd qemu_driver lock has been ( logically ) eliminated.

The 2nd part of the idea is that the sequence of locks (filter, qemu_domain) and (qemu_domain, filter) becomes interchangeable if all code paths where filter AND qemu_domain are locked have a preceding qemu_domain lock that basically blocks their concurrent execution

So, the following code paths exist towards qemu_driver:qemudVMFilterRebuild where we now want to put a qemu_driver lock in front of the filter lock.

-> nwfilterUndefine()   [ locks the filter ]
    -> virNWFilterTestUnassignDef()
        -> virNWFilterTriggerVMFilterRebuild()
            -> qemudVMFilterRebuild()

-> nwfilterDefine()
    -> virNWFilterPoolAssignDef() [ locks the filter ]
        -> virNWFilterTriggerVMFilterRebuild()
            -> qemudVMFilterRebuild()

-> nwfilterDriverReload()
    -> virNWFilterPoolLoadAllConfigs()
        ->virNWFilterPoolObjLoad()
            -> virNWFilterPoolAssignDef() [ locks the filter ]
                -> virNWFilterTriggerVMFilterRebuild()
                    -> qemudVMFilterRebuild()

-> nwfilterDriverStartup()
    -> virNWFilterPoolLoadAllConfigs()
        ->virNWFilterPoolObjLoad()
            -> virNWFilterPoolAssignDef() [ locks the filter ]
                -> virNWFilterTriggerVMFilterRebuild()
                    -> qemudVMFilterRebuild()

Qemu is not the only driver using the nwfilter driver, but also the UML driver calls into it. Therefore qemuVMFilterRebuild() can be exchanged with umlVMFilterRebuild() along with the driver lock of qemu_driver that can now be a uml_driver. Further, since UML and Qemu domains can be running on the same machine, the triggering of a rebuild of the filter can touch both types of drivers and their domains.

In the patch below I am now extending each nwfilter callback driver with functions for locking and unlocking the (VM) driver (UML, QEMU) and introduce new functions for locking all registered callback drivers and unlocking them. Then I am distributing the lock-all-cbdrivers/unlock-all-cbdrivers call into the above call paths. The last shown callpath starting with nwfilterDriverStart() is problematic since it is initialize before the Qemu and UML drives are and thus a lock in the path would result in a NULL pointer attempted to be locked -- the call to virNWFilterTriggerVMFilterRebuild() is never called, so we never lock either the qemu_driver or the uml_driver in that path. Therefore, only the first 3 paths now receive calls to lock and unlock all callback drivers. Now that the locks are distributed where it matters I can remove the qemu_driver and uml_driver lock from qemudVMFilterRebuild() and umlVMFilterRebuild() and not requiring the recursive locks.

For now I want to put this out as an RFC patch. I have tested it by 'stretching' the critical section after the define/undefine functions each lock the filter so I can (easily) concurrently execute another VM operation (suspend,start). That code is in this patch and if you want you can de-activate it. It seems to work ok and operations are being blocked while the update is being done.
I still also want to verify the other assumption above that locking filter and qemu_domain always has a preceding qemu_driver lock.
2010-10-13 10:33:26 -04:00
Guido Günther
b2d7cedeb9 Pass -n to ip(6)tables
to avoid long timeouts waiting for DNS servers
2010-10-08 23:54:03 +02:00
Stefan Berger
5b0c71ee07 nwfilter: Instantiate state match in ip(6)tables rules
In this patch I am extending the rule instantiator to create the state
match according to the state attribute in the XML. Only one iptables
rule in the incoming or outgoing direction will be created for a rule
in direction 'in' or 'out' respectively. A rule in direction 'inout' does
get iptables rules in both directions.
2010-10-07 06:41:37 -04:00
Stefan Berger
2e224f197c nwfilter: fix memory leaks
Fixing memory leak shown by valgrind and freeing buffer in two more places.
2010-10-04 06:34:05 -04:00
Stefan Berger
b00f41a1d2 nwfilter: Instantiate comments in ip(6)tables rules
In this patch I am extending the rule instantiator to create the comment
node where supported, which is the case for iptables and ip6tables.

Since commands are written in the format

cmd='iptables ...-m comment --comment \"\" '

certain characters ('`) in the comment need to be escaped to
prevent comments from becoming commands themselves or cause other
forms of (bash) substitutions. I have tested this with various input and in
my tests the input made it straight into the comment. A test case for TCK
will be provided separately that tests this.
2010-09-30 15:56:09 -04:00
Justin Clift
48005255b0 nwfilter: remove recently added workaround define for macos x
This reverses commit 04c3704, which added a define to nwfilter to
allow libvirtd compilation on Mac OS X.  Stefan Bergers commit, 2e7294d,
is the proper solution, removing the requirement for nwfilter on non-Linux.
2010-09-28 22:41:11 +10:00
Justin Clift
04c3704e70 nwfilter: add a missing define, so libvirtd builds on macos x
The nwfilter code uses ETH_ALEN, which isn't defined on MacOS X.
This is a simple workaround, to add it when missing.
2010-09-28 01:31:52 +10:00
Stefan Berger
570d040435 nwfilter: report if ip(6)tables rules would not be active
The patch below reports a warning in the log if the generated ip(6)tables rules would not be effective due to the proc filesystem entries

    /proc/sys/net/bridge/bridge-nf-call-iptables
    /proc/sys/net/bridge/bridge-nf-call-ip6tables

containing a '0'. The warning tells the user what to do. I am rate-limiting the warning message to appear only every 10 seconds.
2010-09-24 12:06:17 -04:00
Eric Blake
52baf647ca nwfilter: use consistent OOM reporting
* src/nwfilter/nwfilter_driver.c (nwfilterLog): Delete.
(nwfilterDriverStartup): Use virReportOOMError instead.
2010-08-19 13:14:41 -06:00
Stefan Berger
cf6f8b9a97 nwfilter: extend nwfilter reload support
In this patch I am extending and fixing the nwfilter module's reload support to stop all ongoing threads (for learning IP addresses of interfaces) and rebuild the filtering rules of all interfaces of all VMs when libvirt is started. Now libvirtd rebuilds the filters upon the SIGHUP signal and libvirtd restart.

About the patch: The nwfilter functions require a virConnectPtr. Therefore I am opening a connection in qemudStartup, which later on needs to be closed outside where the driver lock is held since otherwise it ends up in a deadlock due to virConnectClose() trying to lock the driver as well.

I have tested this now for a while with several machines running and needing the IP address learner thread(s). The rebuilding of the firewall rules seems to work fine following libvirtd restart or a SIGHUP. Also the termination of libvirtd worked fine.
2010-08-16 12:59:54 -04:00
Stefan Berger
753d76e0cd nwfilter: Discard class D,E IP addresses when sniffing pkts
When sniffing the network traffic, discard class D and E IP addresses when sniffing traffic. This was a reason why filters were not correctly rebuilt on VMs on the local 192.* network when libvirt was restarted and those VMs did not use a DHCP request to get its IP address.
2010-08-13 16:41:39 -04:00
Stefan Berger
bed3a217f6 nwfilter: serialize execution of scripts with ebtables cmds
While testing the SIGHUP handling and reloading of the nwfilter driver, I found that when the filters are rebuilt and mutlipe threads handled the individual interfaces, concurrently running multiple external bash scripts causes strange failures even though the executed ebtables commands are working on different tables for different interfaces. I cannot say for sure where the concurrency problems are caused, but introducing this lock definitely helps.
2010-08-13 15:47:10 -04:00
Stefan Berger
cab5a52aa2 nwfilter: fix loadable module support
Following Daniel Berrange's multiple helpful suggestions for improving
this patch and introducing another driver interface, I now wrote the
below patch where the nwfilter driver registers the functions to
instantiate and teardown the nwfilters with a function in
conf/domain_nwfilter.c called virDomainConfNWFilterRegister. Previous
helper functions that were called from qemu_driver.c and qemu_conf.c
were move into conf/domain_nwfilter.h with slight renaming done for
consistency. Those functions now call the function expored by
domain_nwfilter.c, which in turn call the functions of the new driver
interface, if available.
2010-06-21 14:18:31 -04:00
Stefan Berger
51d3fb0276 nwfilter: add XML attribute to control iptables state match
This patch adds an optional XML attribute to a nwfilter rule to give the user control over whether the rule is supposed to be using the iptables state match or not. A rule may now look like shown in the XML below with the statematch attribute either having value '0' or 'false' (case-insensitive).

[...]
<rule action='accept' direction='in' statematch='false'>
<tcp srcmacaddr='1:2:3:4:5:6'
           srcipaddr='10.1.2.3' srcipmask='32'
           dscp='33'
           srcportstart='20' srcportend='21'
           dstportstart='100' dstportend='1111'/>
</rule>
[...]

I am also extending the nwfilter schema and add this attribute to a test case.
2010-06-17 14:12:34 -04:00
Stefan Berger
2dce970162 nwfilter: use match target on incoming traffic
The following patch enables the iptables match target to be used by
default for incoming traffic. So far it has only be used for outgoing
traffic.
2010-06-17 07:15:20 -04:00
Jim Meyering
0058184c4e ebiptablesWriteToTempFile: don't close a negative file descriptor
* src/nwfilter/nwfilter_ebiptables_driver.c (ebiptablesWriteToTempFile):
Skip the close if "fd" is negative.
2010-05-18 16:55:26 +02:00
Stefan Berger
018fd697b6 nwfilter: skip some interfaces on filter update
When a filter is updated, only those interfaces must have their old
rules cleared that either reference the filter directly or indirectly
through another filter. Remember between the different steps of the
instantiation of the filters which interfaces must be skipped. I am
using a hash map to remember the names of the interfaces and store a
bogus pointer to ~0 into it that need not be freed.
2010-05-03 18:14:58 -04:00
Stefan Berger
5c77fddf4e pass info where request stems from to have rules applied
For the decision on whether to instantiate the rules, the check for a
pending IP address learn request is not sufficient since then only the
thread could instantiate the rules. So, a boolean needs to be passed
when the thread instantiates the filter rules late and the IP address
learn request is still pending in order to override the check for the
pending learn request. If the rules are to be updated while the thread
is active, this will not be done immediately but the thread will do that
later on.
2010-05-03 18:11:48 -04:00
Stefan Berger
5054e89272 Prevent updates while IP address learn thread is running
Prevent updating and tearing down of filter while the IP
address learning thread is running and has its own filtering
rules applied.
2010-04-30 08:12:26 -04:00
Stefan Berger
ebacb31fb5 Syncronize the teardown of rules with the thread
Introduce a function to notify the IP address learning
thread to terminate and thus release the lock on the interface.
Notify the thread before grabbing the lock on the interface
and tearing down the rules. This prevents a 'virsh destroy' to
tear down the rules that the IP address learning thread has
applied.
2010-04-30 08:10:12 -04:00
Stefan Berger
59fe163f2f 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.
2010-04-30 08:06:18 -04:00
Stefan Berger
7c66c033a9 nwfilter: Also pick IP address from a DHCP ACK message
The local DHCP server on virtbr0 sends DHCP ACK messages when a VM is
started and requests an IP address while the initial DHCP lease on the
VM's MAC address hasn't expired. So, also pick the IP address of the VM
if that type of message is seen.
Thanks to Gerhard Stenzel for providing a test case for this.

Changes from V1 to V2:
- cleanup: replacing DHCP option numbers through constants
2010-04-30 07:51:47 -04:00
Stefan Berger
aea68ce906 nwfilter: add support for RAPR protocol
This patch adds support for the RARP protocol. This may be needed due to
qemu sending out a RARP packet (at least that's what it seems to want to
do even though the protocol id is wrong) when migration finishes and
we'd need a rule to let the packets pass.

Unfortunately my installation of ebtables does not understand -p RARP
and also seems to otherwise depend on strings in /etc/ethertype
translated to protocol identifiers. Therefore I need to pass -p 0x8035
for RARP. To generally get rid of the dependency of that file I switch
all so far supported protocols to use their protocol identifier in the
-p parameter rather than the string.

I am also extending the schema and added a test case.

changes from v1 to v2:
- added test case into patch
2010-04-27 07:26:12 -04:00
Stefan Berger
5c7c755f50 nwfilter: enable hex number inputs in filter XML
With this patch I want to enable hex number inputs in the filter XML. A
number that was entered as hex is also printed as hex unless a string
representing the meaning can be found.

I am also extending the schema and adding a test case. A problem with
the DSCP value is fixed on the way as well.

Changes from V1 to V2:

- using asHex boolean in all printf type of functions to select the
output format in hex or decimal format
2010-04-26 13:50:40 -04:00
Daniel P. Berrange
98bd5e6c5a Fix crash in nwfilter driver check
The nwfilterDriverActive() could de-reference a NULL pointer
if it hadn't be started at the point it was called. It was
also not thread safe, since it lacked locking around data
accesses.

* src/nwfilter/nwfilter_driver.c: Fix locking & NULL checks
  in nwfilterDriverActive()
2010-04-23 11:06:30 +01:00
Stefan Berger
647c26c886 Changes from V1 to V2:
- using INT_BUFSIZE_BOUND() to determine the length of the buffersize
for printing and integer into

 - not explicitly initializing static var threadsTerminate to false
anymore, since that's done automatically

Changes after V2:
  - removed while looks in case of OOM error
  - removed on ifaceDown() call
  - preceding one ifaceDown() call with an ifaceCheck() call

Since the name of an interface can be the same between stops and starts
of different VMs I have to switch the IP address learning thread to use
the index of the interface to determine whether an interface is still
available or not - in the case of macvtap the thread needs to listen for
traffic on the physical interface, thus having to time out periodically
to check whether the VM's macvtap device is still there as an indication
that the VM is still alive. Previously the following sequence of 2 VMs
with macvtap device

virsh start testvm1; virsh destroy testvm1 ; virsh start testvm2

would not terminate the thread upon testvm1's destroy since the name of
the interface on the host could be the same (i.e, macvtap0) on testvm1
and testvm2, thus it was easily race-able. The thread would then
determine the IP address parameter for testvm2 but apply the rule set
for testvm1. :-(
I am also introducing a lock for the interface (by name) that the thread
must hold while it listens for the traffic and releases when it
terminates upon VM termination or 0.5 second thereafter. Thus, the new
thread for a newly started VM with the same interface name will not
start while the old one still holds the lock. The only other code that I
see that also needs to grab the lock to serialize operation is the one
that tears down the firewall that were established on behalf of an
interface.

I am moving the code applying the 'basic' firewall rules during the IP
address learning phase inside the thread but won't start the thread
unless it is ensured that the firewall driver has the ability to apply
the 'basic' firewall rules.
2010-04-22 14:58:57 -04:00
Stefan Berger
abce152a49 nwfilter: add support for connlimit match
This patch adds support for the connlimit match in iptables that is used
to limit the number of outgoing directions.
2010-04-20 17:14:38 -04:00
Stefan Berger
c8f4dcca6a Extend fwall-drv interface and call functions via interface
I am moving some of the eb/iptables related functions into the interface
of the firewall driver and am making them only accessible via the driver's
interface. Otherwise exsiting code is adapted where needed. I am adding one
new function to the interface that checks whether the 'basic' rules can be
applied,  which will then be used by a subsequent patch.
2010-04-20 17:07:15 -04:00
Matthias Bolte
051df19e0e Replace printf with logging macros 2010-04-17 15:02:28 +02:00
Jiri Denemark
7a2c6222a9 Use virCheckFlags for APIs added in 0.8.0 2010-04-16 14:05:50 +02:00
Stefan Berger
d2327278fb nwfilter: Clear all state tracking from a drop rule
Don't use state-matching in a drop rule.
2010-04-16 07:34:36 -04:00
Stefan Berger
41b087198d nwfilter: fix tear down order and consolidate functions
To avoid race-conditions, the tear down of a filter has to happen before
the tap interface disappears and another tap interface with the same
name can re-appear. This patch tries to fix this. In one place, where
communication with the qemu monitor may fail, I am only tearing the
filters down after knowing that the function did not fail.

I am also moving the tear down functions into an include file for other
drivers to reuse.
2010-04-15 10:49:24 -04:00
Stefan Berger
c41873f40e Trivial fix: Add braces to for statement to avoid crashes
I am adding braces around the for statement that are now needed to due the
new sa_assert immediately following the for statement.
2010-04-14 21:24:21 -04:00
Jim Meyering
b6719eab9e nwfilter_ebiptables_driver.c: avoid NULL dereference
* src/nwfilter/nwfilter_ebiptables_driver.c (ebiptablesApplyNewRules):
Don't dereference a NULL or uninitialized pointer when given
an empty list of rules.  Add an sa_assert(inst) in each loop to
tell clang that the uses of "inst[i]" are valid.
2010-04-14 20:10:18 +02:00
Stefan Berger
274f09cbc5 nwfilter: use virFindFileInPath for needed CLI tools
I am getting rid of determining the path to necessary CLI tools at
compile time. Instead, now the firewall driver has an initialization
function that uses virFindFileInPath() to determine the path to
necessary CLI tools and a shutdown function to free allocated memory.
The rest of the patch mostly deals with availability of the CLI tools
and to not call certain code blocks if a tool is not available and that
strings now have to be built slightly differently.
2010-04-14 06:29:55 -04:00
Stefan Berger
5174b02fb9 Consolidate interface related functions in interface.c
Changes from v1 to v2:
- changed function name prefixes to 'iface' from previous 'Iface'

- Further to make make syntax-check pass:
 - indentation fix in interface.h
 - added entry to POTFILES.in

I am consolidating network interface related functions used in nwfilter
and macvtap code in utils/interface.c. All function names are prefixed
with 'Iface'. The following functions are now available through
interface.h:

int ifaceCtrl(const char *name, bool up);
int ifaceUp(const char *name);
int ifaceDown(const char *name);

int ifaceCheck(bool reportError, const char *ifname,
               const unsigned char *macaddr, int ifindex);

int ifaceGetIndex(bool reportError, const char *ifname, int *ifindex);

I added 'int ifindex' as parameter to ifaceCheck to the original
function and modified the code accordingly.
2010-04-13 10:57:11 -04:00
Stefan Berger
c5337e8e43 nwfilter: Fix memory leak on daemon init and shutdown
This patch fixes a memory leak on daemon init and shutdown. The module
was initialized twice and not shut down.
2010-04-12 08:19:11 -04:00
Stefan Berger
55d444cc10 nwfilter: Process DHCP option to determine whether packet is a DHCP_OFFER
I mistakenly took the op field in the DHCP message as the DHCP_OFFER
type. Rather than basing the decision to read the VM's IP address on
that field, process the appended DHCP options where option 53 indicates
the actual type of the packet. I am also reading the broadcast address
of the VM, but don't use it so far.
2010-04-09 15:54:29 -04:00
Stefan Berger
9fd54a78dc nwfilter: fix for directionality of ICMP traffic
Changes from V1 to V2 of this patch
- I had reversed the logic thinking that icmp type 0 is a echo
request,but it's reply -- needed to reverse the logic
- Found that ebtables takes the --ip-tos argument only as a hex number

This patch enables the skipping of some of the ICMP traffic rules on the
iptables level under certain circumstances so that the following filter
properly enables unidirectional pings:

<filter name='testcase'>
    <uuid>d6b1a2af-def6-2898-9f8d-4a74e3c39558</uuid>
    <!-- allow incoming ICMP Echo Request -->
    <rule action='accept' direction='in' priority='500'>
        <icmp type='8'/>
    </rule>
    <!-- allow outgoing ICMP Echo Reply -->
    <rule action='accept' direction='out' priority='500'>
        <icmp type='0'/>
    </rule>
    <!-- drop all other ICMP traffic -->
    <rule action='drop' direction='inout' priority='600'>
        <icmp/>
    </rule>
</filter>
2010-04-08 06:25:38 -04:00
Stefan Berger
3bf24abc8c nwfilter: Support for learning a VM's IP address
This patch implements support for learning a VM's IP address. It uses
the pcap library to listen on the VM's backend network interface (tap)
or the physical ethernet device (macvtap) and tries to capture packets
with source or destination MAC address of the VM and learn from DHCP
Offers, ARP traffic, or first-sent IPv4 packet what the IP address of
the VM's interface is. This then allows to instantiate the network
traffic filtering rules without the user having to provide the IP
parameter somewhere in the filter description or in the interface
description as a parameter. This only supports to detect the parameter
IP, which is for the assumed single IPv4 address of a VM. There is not
support for interfaces that may have multiple  IP addresses (IP
aliasing) or IPv6 that may then require more than one valid IP address
to be detected. A VM can have multiple independent interfaces that each
uses a different IP address and in that case it will be attempted to
detect each one of the address independently.

So, when for example an interface description in the domain XML has
looked like this up to now:

    <interface type='bridge'>
      <source bridge='mybridge'/>
      <model type='virtio'/>
      <filterref filter='clean-traffic'>
        <parameter name='IP' value='10.2.3.4'/>
      </filterref>
    </interface>

you may omit the IP parameter:

    <interface type='bridge'>
      <source bridge='mybridge'/>
      <model type='virtio'/>
      <filterref filter='clean-traffic'/>
    </interface>

Internally I am walking the 'tree' of a VM's referenced network filters
and determine with the given variables which variables are missing. Now,
the above IP parameter may be missing and this causes a libvirt-internal
thread to be started that uses the pcap library's API to listen to the
backend interface  (in case of macvtap to the physical interface) in an
attempt to determine the missing IP parameter. If the backend interface
disappears the thread terminates assuming the VM was brought down. In
case of a macvtap device a timeout is being used to wait for packets
from the given VM (filtering by VM's interface MAC address). If the VM's
macvtap device disappeared the thread also terminates. In all other
cases it tries to determine the IP address of the VM and will then apply
the rules late on the given interface, which would have happened
immediately if the IP parameter had been explicitly given. In case an
error happens while the firewall rules are applied, the VM's backend
interface is 'down'ed preventing it to communicate. Reasons for failure
for applying the network firewall rules may that an ebtables/iptables
command failes or OOM errors. Essentially the same failure reasons may
occur as when the firewall rules are applied immediately on VM start,
except that due to the late application of the filtering rules the VM
now is already running and cannot be hindered anymore from starting.
Bringing down the whole VM would probably be considered too drastic.
While a VM's IP address is attempted to be determined only limited
updates to network filters are allowed. In particular it is prevented
that filters are modified in such a way that they would introduce new
variables.

A caveat: The algorithm does not know which one is the appropriate IP
address of a VM. If the VM spoofs an IP address in its first ARP traffic
or IPv4 packets its filtering rules will be instantiated for this IP
address, thus 'locking' it to the found IP address. So, it's still
'safer' to explicitly provide the IP address of a VM's interface in the
filter description if it is known beforehand.

* configure.ac: detect libpcap
* libvirt.spec.in: require libpcap[-devel] if qemu is built
* src/internal.h: add the new ATTRIBUTE_PACKED define
* src/Makefile.am src/libvirt_private.syms: add the new modules and symbols
* src/nwfilter/nwfilter_learnipaddr.[ch]: new module being added
* src/nwfilter/nwfilter_driver.c src/conf/nwfilter_conf.[ch]
  src/nwfilter/nwfilter_ebiptables_driver.[ch]
  src/nwfilter/nwfilter_gentech_driver.[ch]: plu the new functionality in
* tests/nwfilterxml2xmltest: extend testing
2010-04-07 23:12:21 +02:00
Stefan Berger
f8352e221f nwfiler: fix due to non-symmetric src mac address match in iptables
The attached patch fixes a problem due to the mac match in iptables only
supporting --mac-source and no --mac-destination, thus it not being
symmetric. Therefore a rule like this one

<rule action='drop' direction='out'>
  <all match='no' srcmacaddr='$MAC'/>
</rule>

should only have the MAC match on traffic leaving the VM and not test
for the same source MAC address on traffic that the VM receives.
2010-04-07 06:28:16 -04:00
Stefan Berger
552bdb9b35 nwfilter: Fix instantiated layer 2 rules for 'inout' direction
With Eric Blake's suggestions applied.

The following rule for direction 'in'

<rule direction='in' action='drop'>
  <mac srcmacaddr='1:2:3:4:5:6'/>
</rule>

drops all traffic from the given mac address.
The following rule for direction 'out'

<rule direction='out' action='drop'>
  <mac dstmacaddr='1:2:3:4:5:6'/>
</rule>

drops all traffic to the given mac address.
The following rule in direction 'inout'

<rule direction='inout' action='drop'>
  <mac srcmacaddr='1:2:3:4:5:6'/>
</rule>

now drops all traffic from and to the given MAC address.
So far it would have dropped traffic from the given MAC address
and outgoing traffic with the given source MAC address, which is not useful
since the packets will always have the VM's MAC address as source
MAC address. The attached patch fixes this.

This is the last bug I currently know of and want to fix.
2010-04-06 10:40:35 -04:00
Matthias Bolte
49411f029a Remove unnecessary trailing \n in log messages 2010-04-06 01:41:58 +02:00
Stefan Berger
45274d4121 This patch removes the virConnectPtr parameter from all functions where it's not necessary starting out with removing it as a parameter to the error reporting function. 2010-04-05 12:34:55 -04:00