Commit Graph

378 Commits

Author SHA1 Message Date
Nikolay Shirokovskiy
01e11ebcb6 nwfilter: fix adding std MAC and IP values to filter binding
Commit d1a7c08eb changed filter instantiation code to ignore MAC and IP
variables explicitly specified for filter binding. It just replaces
explicit values with values associated with the binding. Before the
commit virNWFilterCreateVarsFrom was used so that explicit value
take precedence. Let's bring old behavior back.

This is useful. For example if domain has two interfaces it makes
sense to list both mac adresses in MAC var of every interface
filterref. So that if guest make a bond of these interfaces
and start sending frames with one of the mac adresses from
both interfaces we can pass outgress traffic from both
interfaces too.

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy@virtuozzo.com>
2019-03-22 12:03:00 +03:00
Ján Tomko
0f110d5ac8 Use NULLSTR_EMPTY
Instead of repetitive:
  s ? s : ""
use NULLSTR_EMPTY.

Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Andrea Bolognani <abologna@redhat.com>
2019-02-14 14:09:38 +01:00
Laine Stump
4bf0f390ed configure: change HAVE_FIREWALLD to WITH_FIREWALLD
Support for firewalld is a feature that can be selectively enabled or
disabled (using --with-firewalld/--without-firewalld), not merely
something that must be accounted for in the code if it is present with
no exceptions. It is more consistent with other usage in libvirt to
use WITH_FIREWALLD rather than HAVE_FIREWALLD.

Signed-off-by: Laine Stump <laine@laine.org>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
2019-02-01 12:08:37 -05:00
Daniel P. Berrangé
b092a4357d util: pass layer into firewall query callback
Some of the query callbacks want to know the firewall layer that was
being used for triggering the query to avoid duplicating that data.

Reviewed-by: Laine Stump <laine@laine.org>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2019-01-29 13:35:58 +00:00
Daniel P. Berrangé
568a417224 Enforce a standard header file guard symbol name
Require that all headers are guarded by a symbol named

  LIBVIRT_$FILENAME

where $FILENAME is the uppercased filename, with all characters
outside a-z changed into '_'.

Note we do not use a leading __ because that is technically a
namespace reserved for the toolchain.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-12-14 10:47:13 +00:00
Daniel P. Berrangé
4cfd709021 Fix many mistakes & inconsistencies in header file layout
This introduces a syntax-check script that validates header files use a
common layout:

  /*
   ...copyright header...
   */
  <one blank line>
  #ifndef SYMBOL
  # define SYMBOL
  ....content....
  #endif /* SYMBOL */

For any file ending priv.h, before the #ifndef, we will require a
guard to prevent bogus imports:

  #ifndef SYMBOL_ALLOW
  # error ....
  #endif /* SYMBOL_ALLOW */
  <one blank line>

The many mistakes this script identifies are then fixed.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-12-14 10:46:53 +00:00
Daniel P. Berrangé
600462834f Remove all Author(s): lines from source file headers
In many files there are header comments that contain an Author:
statement, supposedly reflecting who originally wrote the code.
In a large collaborative project like libvirt, any non-trivial
file will have been modified by a large number of different
contributors. IOW, the Author: comments are quickly out of date,
omitting people who have made significant contribitions.

In some places Author: lines have been added despite the person
merely being responsible for creating the file by moving existing
code out of another file. IOW, the Author: lines give an incorrect
record of authorship.

With this all in mind, the comments are useless as a means to identify
who to talk to about code in a particular file. Contributors will always
be better off using 'git log' and 'git blame' if they need to  find the
author of a particular bit of code.

This commit thus deletes all Author: comments from the source and adds
a rule to prevent them reappearing.

The Copyright headers are similarly misleading and inaccurate, however,
we cannot delete these as they have legal meaning, despite being largely
inaccurate. In addition only the copyright holder is permitted to change
their respective copyright statement.

Reviewed-by: Erik Skultety <eskultet@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-12-13 16:08:38 +00:00
Yuri Chornoivan
e5c1fbca24 Fix minor typos in messages and docs
Signed-off-by: Yuri Chornoivan <yurchor@ukr.net>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: Ján Tomko <jtomko@redhat.com>
2018-12-05 10:39:54 +01:00
Nikolay Shirokovskiy
67125e0d33 nwfilter: Instantiate active filter bindings during driver init
Commit 57f5621f modified nwfilterInstantiateFilter to detect when
a filter binding was already present before attempting to add the
new binding and instantiate it. Additionally, the change to
nwfilterStateInitialize to call virNWFilterBindingObjListLoadAllConfigs
(from commit c21679fa3f) to load active domain filter bindings, but
not instantiate them eventually leads to a problem for the QEMU
driver reconnection logic after a daemon restart where the filter
bindings would no longer be instantiated.

Subsequent commit f14c37ce4c replaced the nwfilterInstantiateFilter
with virDomainConfNWFilterInstantiate which uses @ignoreExists to
detect presence of the filter and still did not restore the filter
instantiation call when making the new nwfilter bindings logic active.

Thus in order to instantiate any active domain filter, we will call
virNWFilterBuildAll with 'false' to indicate the need to go through
all the active bindings calling virNWFilterInstantiateFilter to
instantiate the filter bindings.

Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy@virtuozzo.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
2018-11-05 07:10:47 -05:00
Nikolay Shirokovskiy
49825dcf31 nwfilter: Fix learning address thread shutdown
If the learning thread is configured to learn on all ethernet frames
(which is hardcoded) then chances are high that there is a packet on
every iteration of inspecting frames loop. As result we will hang on
shutdown because we don't check threadsTerminate if there is packet.

Let's just check termination conditions on every iteration. Since
we'll check each iteration, the check after pcap_next essentially
is unnecessary since on failure we'd loop back to the top and timeout
and then fail.

Signed-off-by: Nikolay Shirokovskiy <nshirokovskiy@virtuozzo.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
2018-10-17 17:06:04 -04:00
John Ferlan
3a286a4e26 nwfilter: Alter virNWFilterSnoopReqLeaseDel logic
Move the fetch of @ipAddrLeft to after the goto skip_instantiate
and remove the (req->binding) guard since we know that as long
as req->binding is created, then req->threadkey is filled in.

Found by Coverity

Signed-off-by: John Ferlan <jferlan@redhat.com>
ACKed-by: Michal Privoznik <mprivozn@redhat.com>
2018-10-01 14:27:47 -04:00
John Ferlan
e3a42028af Remove ignore_value or void from unlink calls
There seems to be no need to add the ignore_value wrapper or
caste with (void) to the unlink() calls, so let's just remove
them. I assume at one point in time Coverity complained. So,
let's just be consistent - those that care to check the return
status can and those that don't can just have the naked unlink.

Signed-off-by: John Ferlan <jferlan@redhat.com>
Reviewed-by: Erik Skultety <eskultet@redhat.com>
2018-09-20 13:45:56 -04:00
Erik Skultety
5165ff0971 src: More cleanup of some system headers already contained in internal.h
All of the ones being removed are pulled in by internal.h. The only
exception is sanlock which expects the application to include <stdint.h>
before sanlock's headers, because sanlock prototypes use fixed width
int, but they don't include stdint.h themselves, so we have to leave
that one in place.

Signed-off-by: Erik Skultety <eskultet@redhat.com>
Acked-by: Michal Privoznik <mprivozn@redhat.com>
2018-09-20 10:16:39 +02:00
Shi Lei
c9ed87a610 src: remove blank first line in function body
Signed-off-by: Shi Lei <shi_lei@massclouds.com>
2018-09-17 13:29:01 +02:00
John Ferlan
e773e1cbbc nwfilter: Disallow binding creation in session mode
Similar to nwfilterDefineXML, let's be sure the a filter binding
creation is not attempted in session mode and generate the proper
error message.

Failure to open nwfilter in session mode (nwfilterConnectOpen)
fails already, but that doesn't stop the free thinker from using
a different connection in order to attempt to attempt to create
the binding. Although even doing that would result in a failure:

$ virsh nwfilter-binding-create QEMUGuest1-binding.xml
error: Failed to create network filter from QEMUGuest1-binding.xml
error: internal error: Could not get access to ACL tech driver 'ebiptables'

$

Signed-off-by: John Ferlan <jferlan@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
2018-09-06 18:38:06 -04:00
John Ferlan
5229494b01 nwfilter: Resolve SEGV for NWFilter Snoop processing
https://bugzilla.redhat.com/show_bug.cgi?id=1599973

Commit id fca9afa08 changed the @req->ifname to use
@req->binding->portdevname fillingin the @req->binding
in a similar way that @req->ifname would have been
filled in during virNWFilterDHCPSnoopReq processing.

However, in doing so it did not take into account some
code paths where the @req->binding should be checked
instead of @req->binding->portdevname. These checks
led to SEGVs in some cases during libvirtd reload
processing in virNWFilterSnoopRemAllReqIter (for
stop during nwfilterStateCleanup processing) and
virNWFilterSnoopReqLeaseDel (for start during
nwfilterStateInitialize processing).

In particular, when reading the nwfilter.leases file
a new @req is created, but the @req->binding is not
filled in. That's left to virNWFilterDHCPSnoopReq
processing which checks if the @req already exists
in the @virNWFilterSnoopState.snoopReqs hash table
after adding a virNWFilterSnoopState.ifnameToKey
entry for the @req->binding->portdevname by a
@ref->ikey value.

NB: virNWFilterSnoopIPLeaseInstallRule and
    virNWFilterDHCPSnoopThread do not need the
    req->binding check since they can only be called
    after the filter->binding is created/assigned.

Signed-off-by: John Ferlan <jferlan@redhat.com>
ACKed-by: Michal Privoznik <mprivozn@redhat.com>
2018-07-26 09:35:40 -04:00
Andrea Bolognani
6c0d0210cb src: Make virStr*cpy*() functions return an int
Currently, the functions return a pointer to the
destination buffer on success or NULL on failure.

Not only does this kind of error handling look quite
alien in the context of libvirt, where most functions
return zero on success and a negative int on failure,
but it's also somewhat pointless because unless there's
been a failure the returned pointer will be the same
one passed in by the user, thus offering no additional
value.

Change the functions so that they return an int
instead.

Signed-off-by: Andrea Bolognani <abologna@redhat.com>
2018-07-23 14:27:30 +02:00
Pavel Hrdina
3379193f1c nwfilter: Remove redundant check if object exists
The same check is done by virNWFilterBindingObjListAdd().  The main
issue with the current code is that if the object already exists we
would leak 'def' because 'obj' would be set and the cleanup code frees
'def' only if 'obj' is NULL.

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
2018-07-04 07:23:08 +02:00
Julio Faracco
f8c65481d5 nwfilter: variable 'obj' must be initialized inside nwfilterBindingCreateXML().
The function nwfilterBindingCreateXML() is failing to compile due to a
conditional branch which leads to an undefined 'obj' variable. So 'obj'
must have an initial value to avoid compilation errors. See the problem:

  CC       nwfilter/libvirt_driver_nwfilter_impl_la-nwfilter_driver.lo
nwfilter/nwfilter_driver.c:752:9: error: variable 'obj' is used uninitialized whenever 'if' condition is true [-Werror,-Wsometimes-uninitialized]
    if (virNWFilterBindingCreateXMLEnsureACL(conn, def) < 0)
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
nwfilter/nwfilter_driver.c:779:10: note: uninitialized use occurs here
    if (!obj)
         ^~~
nwfilter/nwfilter_driver.c:752:5: note: remove the 'if' if its condition is always false
    if (virNWFilterBindingCreateXMLEnsureACL(conn, def) < 0)
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
nwfilter/nwfilter_driver.c:742:33: note: initialize the variable 'obj' to silence this warning
    virNWFilterBindingObjPtr obj;
                                ^
                                 = NULL

This commit initialized 'obj' with NULL to fix the error properly.

Signed-off-by: Julio Faracco <jcfaracco@gmail.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
2018-06-28 09:44:28 +02:00
Daniel P. Berrangé
f14c37ce4c nwfilter: convert virt drivers to use public API for nwfilter bindings
Remove the callbacks that the nwfilter driver registers with the domain
object config layer. Instead make the current helper methods call into
the public API for creating/deleting nwfilter bindings.

Reviewed-by: John Ferlan <jferlan@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-06-26 18:17:23 +01:00
Daniel P. Berrangé
2d9318b6ce nwfilter: wire up new APIs for creating and deleting nwfilter bindings
This allows the virsh commands nwfilter-binding-create and
nwfilter-binding-delete to be used.

Note using these commands lets you delete filters that were
previously created automatically by the virt drivers, or add
filters for VM nics that were not there before. Generally it
is expected these new APIs will only be used by virt drivers.
It is the admin's responsibility to not shoot themselves in
the foot.

Reviewed-by: John Ferlan <jferlan@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-06-26 18:17:21 +01:00
Daniel P. Berrangé
f61ea979a4 nwfilter: wire up new APIs for listing and querying filter bindings
Wire up the ListAll, LookupByPortDev and GetXMLDesc APIs to allow the
virsh nwfilter-binding-list & nwfilter-binding-dumpxml commands to
work.

Reviewed-by: John Ferlan <jferlan@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-06-26 18:17:21 +01:00
Daniel P. Berrangé
3df907bfff nwfilter: remove virt driver callback layer for rebuilding filters
Now that the nwfilter driver keeps a list of bindings that it has
created, there is no need for the complex virt driver callbacks. It is
possible to simply iterate of the list of recorded filter bindings.

This means that rebuilding filters no longer has to acquire any locks on
the virDomainObj objects, as they're never touched.

Reviewed-by: John Ferlan <jferlan@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-06-26 18:17:20 +01:00
Daniel P. Berrangé
57f5621f46 nwfilter: keep track of active filter bindings
Currently the nwfilter driver does not keep any record of what filter
bindings it has active. This means that when it needs to recreate
filters, it has to rely on triggering callbacks provided by the virt
drivers. This introduces a hash table recording the virNWFilterBinding
objects so the driver has a record of all active filters.

Reviewed-by: John Ferlan <jferlan@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-06-26 18:17:13 +01:00
Daniel P. Berrangé
fca9afa084 nwfilter: convert DHCP address snooping code to virNWFilterBindingDefPtr
Use the virNWFilterBindingDefPtr struct in the DHCP address snooping code
directly.

Reviewed-by: John Ferlan <jferlan@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-06-26 11:22:07 +01:00
Daniel P. Berrangé
5b6c02e292 nwfilter: convert IP address learning code to virNWFilterBindingDefPtr
Use the virNWFilterBindingDefPTr struct in the IP address learning code
directly.

Reviewed-by: John Ferlan <jferlan@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-06-26 11:22:07 +01:00
Daniel P. Berrangé
d1a7c08eb1 nwfilter: convert the gentech driver code to use virNWFilterBindingDefPtr
Use the virNWFilterBindingDefPtr struct in the gentech driver code
directly.

Reviewed-by: John Ferlan <jferlan@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-06-26 11:22:07 +01:00
Brijesh Singh
c04d452ef6 nwfilter: fix build error when pcap-config is not present
The compilation fails with the following error when pcap-config
is not present on the host:

nwfilter/nwfilter_learnipaddr.c:824:1: error: conflicting types for 'virNWFilterLearnIPAddress'
 virNWFilterLearnIPAddress(virNWFilterTechDriverPtr techdriver ATTRIBUTE_UNUSED,

 In file included from nwfilter/nwfilter_learnipaddr.c:57:0:
 nwfilter/nwfilter_learnipaddr.h:38:5: note: previous declaration of 'virNWFilterLearnIPAddress' was here
  int virNWFilterLearnIPAddress(virNWFilterTechDriverPtr techdriver,

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: Ján Tomko <jtomko@redhat.com>
2018-06-07 23:00:16 +02:00
Daniel P. Berrangé
ab4591f1f4 nwfilter: directly use poll to wait for packets instead of pcap_next
When a QEMU VM shuts down its TAP device gets deleted while nwfilter
IP address learning thread is still capturing packets. It is seen that
with TPACKET_V3 support in libcap, the pcap_next() call will not always
exit its poll() when the NIC is removed. This prevents the learning
thread from exiting which blocks the rest of libvirtd waiting on mutex
acquisition. By switching to do poll() in libvirt code, we can ensure
that we always exit the poll() at a time that is right for libvirt.

Reviewed-by: John Ferlan <jferlan@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-06-07 16:59:33 +01:00
Daniel P. Berrangé
1e49132dde nwfilter: fix IP address learning
In a previous commit:

  commit d4bf8f4150
  Author: Daniel P. Berrangé <berrange@redhat.com>
  Date:   Wed Feb 14 09:43:59 2018 +0000

    nwfilter: handle missing switch enum cases

    Ensure all enum cases are listed in switch statements, or cast away
    enum type in places where we don't wish to cover all cases.

    Reviewed-by: John Ferlan <jferlan@redhat.com>
    Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>

we changed a switch in the nwfilter learning thread so that it had
explict cases for all enum entries. Unfortunately the parameters in the
method had been declared with incorrect type. The "howDetect" parameter
does *not* accept "enum howDetect" values, rather it accepts a bitmask
of "enum howDetect" values, so it should have been an "int" type.

The caller always passes DETECT_STATIC|DETECT_DHCP, so essentially the
IP addressing learning was completely broken by the above change, as it
never matched any switch case, hitting the default leading to EINVAL.

Stop using a typedef for the parameter name this this is a bitmask,
not a plain enum value. Also stop using switch() since that's misleading
with bitmasks too.

Reviewed-by: John Ferlan <jferlan@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-06-07 16:58:33 +01:00
Martin Kletzander
cf057fbefb nwfilter/: Remove spaces after casts
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2018-05-03 22:31:37 +02:00
Daniel P. Berrangé
23ed8eb21d nwfilter: pass vm name in when instantiating filters
The vm name is not needed for any functional requirement, but it will be
useful when debugging problems to identify which VM is associated with a
filter, since UUID is not human friendly.

Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-05-03 17:00:57 +01:00
Daniel P. Berrangé
1c425d735d nwfilter: fix leaking of filter parameters upon error
The filter parameters were not correctly free'd when an error hits while
adding to the hash table.

Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-05-03 17:00:57 +01:00
Daniel P. Berrangé
94d31e7c0e nwfilter: remove obsolete code related to firewalld
There is a bunch of left over code in the nwfilter driver related to
monitoring firewalld over dbus, that is no longer used since the
conversion to use virFirewall APIs.

Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-05-03 17:00:57 +01:00
Daniel P. Berrangé
fdc7ebfb54 nwfilter: make virNWFilterIPAddrLearnReq type private
The virNWFilterIPAddrLearnReq type should only be used by the IP address
learning code, so can live in the implementation file instead of header
file.

Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-05-03 17:00:57 +01:00
Daniel P. Berrangé
b6ac5a82b9 nwfilter: change methods returning virNWFilterIPAddrLearnReq to use bool
Various methods return a virNWFilterIPAddrLearnReq struct, but the
callers are only interested in whether the return value is non-NULL.
It is thus preferrable to just return a bool.

Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-05-03 17:00:57 +01:00
Daniel P. Berrangé
d60896321b nwfilter: remove virNWFilterHashTable typedefs entirely
All the code now just uses the virHashTablePtr type directly.

Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-05-03 17:00:57 +01:00
Daniel P. Berrangé
1cf16d755e nwfilter: remove methods that are trivial wrappers for virHash APIs
This removes the virNWFilterHashTableFree, virNWFilterHashTablePut
and virNWFilterHashTableRemove methods, in favour of just calling
the virHash APIs directly.

The virNWFilterHashTablePut method was unreasonably complex because
the virHashUpdateEntry already knows how to create the entry if it
does not currently exist.

Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-05-03 17:00:57 +01:00
Daniel P. Berrangé
77646d9478 nwfilter: remove pointless virNWFilterHashTable struct
The virNWFilterHashTable struct only contains a single virHashTable
member since

  commit 293d4fe2f1
  Author: Daniel P. Berrange <berrange@redhat.com>
  Date:   Mon Mar 24 16:35:23 2014 +0000

    Remove pointless storage of var names in virNWFilterHashTable

Thus, this struct wrapper adds no real value over just using the
virHashTable directly, but brings the complexity of needing to derefence
the hashtable to call virHash* APIs, and adds extra memory allocation
step.

To minimize code churn this just turns virNWFilterHashTable into a
typedef aliases virHashTable.

Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-05-03 17:00:57 +01:00
Laine Stump
ce5aebeacd nwfilter: increase pcap buffer size to be compatible with TPACKET_V3
When an nwfilter rule sets the parameter CTRL_IP_LEARNING to "dhcp",
this turns on the "dhcpsnoop" thread, which uses libpcap to monitor
traffic on the domain's tap device and extract the IP address from the
DHCP response.

If libpcap on the host is built with HAVE_TPACKET3 defined (to enable
support for TPACKET_V3), the dhcpsnoop code's initialization of the
libpcap socket would fail with the following error:

  virNWFilterSnoopDHCPOpen:1134 : internal error: pcap_setfilter: can't remove kernel filter: Bad file descriptor

It turns out that this was because TPACKET_V3 requires a larger buffer
size than libvirt was setting (we were setting it to 128k). Changing
the buffer size to 256k eliminates the error, and the dhcpsnoop thread
once again works properly.

A fuller explanation of why TPACKET_V3 requires such a large buffer,
for future git spelunkers:

libpcap calls setsockopt(... SOL_PACKET, PACKET_RX_RING...) to setup a
ring buffer for receiving packets; two of the attributes sent to this
API are called tp_frame_size, and tp_frame_nr. If libpcap was built
with HAVE_TPACKET3 defined, tp_trame_size is set to MAXIMUM_SNAPLEN
(defined in libpcap sources as 262144) and tp_frame_nr is set to:

 [the buffer size we set, i.e. PCAP_BUFFERSIZE i.e. 262144] / tp_frame_size.

So if PCAP_BUFFERSIZE < MAXIMUM_SNAPLEN, then tp_frame_nr (the number
of frames in the ring buffer) is 0, which is nonsensical. This same
value is later used as a multiplier to determine the size for a call
to malloc() (which would also fail).

(NB: if HAVE_TPACKET3 is *not* defined, then tp_frame_size is set to
the snaplen set by the user (in our case 576) plus a small amount to
account for ethernet headers, so 256k is far more than adequate)

Since the TPACKET_V3 code in libpcap actually reads multiple packets
into each frame, it's not a problem to have only a single frame
(especially when we are monitoring such infrequent traffic), so it's
okay to set this relatively small buffer size (in comparison to the
default, which is 2MB), which is important since every guest using
dhcp snooping in a nwfilter rule will hold 2 of these buffers for the
entire life of the guest.

Thanks to Christian Ehrhardt for discovering that buffer size was the
problem (this was not at all obvious from the error that was logged!)

Resolves: https://bugzilla.redhat.com/1547237
Fixes: https://bugs.launchpad.net/libvirt/+bug/1758037

Signed-off-by: Laine Stump <laine@laine.org>
Reviewed-by: Christian Ehrhardt <christian.ehrhardt@canonical.com> (V1)
Reviewed-by: John Ferlan <jferlan@redhat.com>
Tested-by: Christian Ehrhardt <christian.ehrhardt@canonical.com>
2018-04-27 17:38:53 -04:00
Daniel P. Berrangé
4c8574c85c driver: ensure NULL URI isn't passed to drivers with whitelisted URIs
Ensuring that we don't call the virDrvConnectOpen method with a NULL URI
means that the drivers can drop various checks for NULL URIs. These were
not needed anymore since the probe functionality was split

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-04-12 16:52:02 +01:00
Daniel P. Berrangé
8e4f9a2773 driver: declare supported URI schemes in virConnectDriver struct
Declare what URI schemes a driver supports in its virConnectDriver
struct. This allows us to skip trying to open the driver entirely
if the URI scheme doesn't match.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-04-12 16:52:02 +01:00
Daniel P. Berrangé
3714cc952d driver: allow drivers to indicate if they permit remote connections
Add a localOnly flag to the virConnectDriver struct which allows a
driver to indicate whether it is local-only, or permits remote
connections. Stateful drivers running inside libvirtd are generally
local only. This allows us to remote the check for uri->server != NULL
from most drivers.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-04-12 16:52:02 +01:00
Ján Tomko
1943d89b72 Replace QEmu with QEMU
QEMU is the preferred spelling used on QEMU website.

Signed-off-by: Ján Tomko <jtomko@redhat.com>
2018-04-01 17:42:29 +02:00
Ján Tomko
1efdab281f nwfilter: remove pointless assignment
Changing a parameter passed by value has no effect.

Introduced by <commit 3f74b2eb>.

Signed-off-by: Ján Tomko <jtomko@redhat.com>
2018-03-08 16:45:54 +01:00
Daniel P. Berrangé
684388d902 make: split nwfilter driver build rules into nwfilter/Makefile.inc.am
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-03-05 17:09:08 +00:00
Laine Stump
1297db7414 nwfilter: save error from DHCP snoop thread to report in main thread
A problem encountered due to a bug in libpcap was reported to the
caller as:

   An error occurred, but the cause is unknown

This was because the error had been logged in the DHCPSnoop
thread. The worker thread handling the API call to start a domain
spins up the DHCPSnoop thread which watches for dhcp packets with
libpcap, then uses virCondSignal() to notify the worker thread (which
has been waiting with virCondWait()). The worker thread knows that
there was an error (because threadStatus != THREAD_STATUS_OK), but the
error info had been stored in thread-specific storage for the other
thread, so the worker thread can only report that there was a failure,
but it doesn't know why.

The solution is to save the error that was logged (with
virErrorPreserveLast() into the object the is used to share info
between the threads, then we can set the error in the worker thread
using virErrorRestore().

In the case of the error I was looking at, this changed the "unknown"
message into:

    internal error: pcap_setfilter: can't remove kernel filter:
    Bad file descriptor

Signed-off-by: Laine Stump <laine@laine.org>
2018-02-27 12:32:46 -05:00
Daniel P. Berrangé
d4bf8f4150 nwfilter: handle missing switch enum cases
Ensure all enum cases are listed in switch statements, or cast away
enum type in places where we don't wish to cover all cases.

Reviewed-by: John Ferlan <jferlan@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-02-21 16:58:25 +00:00
Laine Stump
f565321b26 nwfilter: assure virNWFilterSnoop(Eth|Dhcp)Hdr structs don't change size
These two objects are used to access fields in actual ethernet packets
captures with libpcap, so it's essential that they don't change size
for any reason. This patch uses gnulib's verify() macro to make sure
their sizes don't change.

Signed-off-by: Laine Stump <laine@laine.org>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
2018-02-20 13:43:21 -05:00
Daniel P. Berrangé
1292de7ef1 nwfilter: allow opening with nwfilter:///system URI
Allow the possibility of opening a connection to only the storage
driver, by defining a nwfilter:///system URI and registering a fake
hypervisor driver that supports it.

The hypervisor drivers can now directly open a nwfilter driver
connection at time of need, instead of having to pass around a
virConnectPtr through many functions. This will facilitate the later
change to support separate daemons for each driver.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
2018-01-31 17:45:16 +00:00