Commit graph

196 commits

Author SHA1 Message Date
Thomas Haller
347555795f route-manager: add argument @ignore_kernel_routes to route_sync()
Will be used later, no behavioral change yet.
2015-07-01 16:02:10 +02:00
Thomas Haller
d9dba6b662 platform: change NMPlatformGetRouteMode enum to NMPlatformGetRouteFlags flags
By having flags instead of an enum/mode, we can encode more combinations
of filtering the result.
2015-07-01 16:00:21 +02:00
Lubomir Rintel
5dc23a28f8 ipx-config: fix test
Fixes: c942a8c35b
2015-06-28 21:34:47 +02:00
Thomas Haller
e8e455817b platform: refactor virtual methods for link objects in NMPlatform
Change nm_platform_link_get() to return the cached NMPlatformLink
instance. Now what all our implementations (fake and linux) have such a
cache internal object, let's just expose it directly.
Note that the lifetime of the exposed link object is possibly quite
short. A caller must copy the returned value if he intends to preserve
it for later.
Also add nm_platform_link_get_by_ifname() and modify nm_platform_link_get_by_address()
to return the instance.

Certain functions, such as nm_platform_link_get_name(),
nm_platform_link_get_ifindex(), etc. are solely implemented based
on looking at the returned NMPlatformLink object. No longer implement
them as virtual functions but instead implement them in the base class
(nm-platform.c).
This removes code and eliminates the redundancy of the exposed
NMPlatformLink instance and the nm_platform_link_get_*() accessors.
Thereby also fix a bug in NMFakePlatform that tracked the link address
in a separate "address" field, instead of using "link.addr". That was
a case where the redundancy actually led to a bug in fake platform.

Also remove some stub implementations in NMFakePlatform that just
bail out. Instead allow for a missing virtual functions and perform
the "default" action in the accessor.
An example for that is nm_platform_link_get_permanent_address().
2015-06-21 12:53:48 +02:00
Thomas Haller
c1a945b95d platform: signal missing firmware in nm_platform_set_up()
Don't use nm_platform_get_error() anymore.
2015-06-17 11:44:16 +02:00
Thomas Haller
d7fe907c32 platform: return NMPlatformError from link-add functions
Later remove nm_platform_get_error() and signal errors via return
error codes.

Also, fix nm_platform_infiniband_partition_add() and
nm_platform_vlan_add() to check the type of the existing link
and fail with WRONG_TYPE otherwise.
2015-06-17 11:44:16 +02:00
Thomas Haller
3359dddd2e Revert "core: add NMRefString"
After hiding the udi field, there are no more users of NMRefString.
Remove the code by explitly reverting the patch so that in case of a future
need, we can find and resurrect NMRefString.

This reverts commit 430658b17a.
2015-06-17 11:44:12 +02:00
Thomas Haller
470bcefa5f platform: use new platform caching
Switch platform caching implementation. Instead of caching libnl
objects, cache our own types.

Don't remove yet the now obsolete functions.

Advantage:

* Performance
  - as we now cache our native NMPlatformObject instances, we no longer
    have to convert libnl objects every time we access the platform
    cache.
  - for most cases, access is now O(1) because we can lookup the object
    in a hash table. Note that ip4_address_get_all() still has to
    create a copy of the result (O(n)), but as the caller is about to
    use those elements, he cannot do better then O(n) anyway.

* We cache our own native types and have full control over them. We
  cannot extend the libnl objects, which has many short-commings:
  - _rtnl_addr_hack_lifetimes_rel_to_abs() to convert the timestamps
    to absolute values (and back).
  - hack_empty_master_iff_lower_up() would modify the internal flag,
    but it looses the original value. That means, we can only hack
    the state before putting a link into the cache, but we cannot revert
    that change, when a slave in the cache changes state.
    That was previously solved by always refetching the master when
    a slave changed. Now we can re-evaluate the connected state
    (DELAYED_ACTION_TYPE_MASTER_CONNECTED).
  - we implement functions like equality, to-string as most suitable
    for us. Before we needed hacks like nm_nl_object_diff(),
    nm_nl_cache_search(), route_search_cache().
  - we can extend our objects with exactly those properties we care,
    and possibly additional properties that are not representable in
    the libnl objects.
  - we no longer cache RTM_F_CLONED routes and they get rejected early
    on as we receive them.
  - In the future, maybe it'd be interesting the make platform objects
    immutable (and ref-counted) and expose them directly.

* Previous implementation did not order the refresh of objects but
  called check_cache_items(). Now, those actions are delayed and
  combined in an attempt to reduce the overall number of reloads.
  Realize how expensive a check_cache_items() for addresses and routes
  was: it would iterate all addresses/routes and call refresh_object().
  The latter obtains a full dump of *all* objects again, and ignores
  all but the needle.
  Note that we probably still schedule some delayed actions that
  are not needed.
  Later we can optimize that further (related bug bgo #747985).

While some of these points could also have been implemented with
caching of libnl objects, that would have become hard to maintain.

https://bugzilla.gnome.org/show_bug.cgi?id=747981
2015-06-17 11:41:42 +02:00
Thomas Haller
f99723eda5 core: add NMMultiIndex class
A class to do efficient lookup for multiple values based on a key.

The values are opaque pointers (void*). These values can be
associated with keys. The keys are an opaque type NMMultiIndexId
with arbitrary hash/equal functions.

Think of the keys being a set of buckets. A value can be associated with multiple
keys, just like with a regular GHashTable (i.e. it can be in multiple buckets).
But one key can also be associated with multiple values (i.e. one bucket can contain
multiple values). Hence the name "multi".
One bucket can only either contain a value or not. It cannot contain the same
value multiple times.

This is implemented as a hash of hashes with the outer keys being
NMMultiIndexId. The inner hashes are the "buckets".

This class will be used as an efficient lookup index to find all values
that belong to a certain key (bucket). Later we will ask for example
"Which IP4-Addresses are associated with a certain ifindex" and
efficiently retrieve the cached result list.
2015-06-17 11:23:51 +02:00
Thomas Haller
430658b17a core: add NMRefString
NMRefString is a simple, refcounted, immutable string. Increasing/decreasing
the refcount does not affect const-ness.

It can be used just like a regular 'const char *' pointer. The only
difference is that you need special alloc/free functions.
2015-06-17 11:23:42 +02:00
Thomas Haller
619f660a3e platform: add scope parameter to NMPlatformIP4Route
Cache the scope as part of the NMPlatformIP4Route and
no longer read it from libnl object when needed. Later
there will be no more libnl objects around, and we need
to scope when deleting an IPv4 route.
2015-06-17 10:53:55 +02:00
Jiří Klimeš
94a393e9ed all: fix a compiler warning about function declarations
warning: function declaration isn’t a prototype [-Wstrict-prototypes]

In C function() and function(void) are two different prototypes (as opposed to
C++).
function()     accepts an arbitrary number of arguments
function(void) accepts zero arguments
2015-06-10 10:01:49 +02:00
Thomas Haller
dc0193ac02 config: support a [connection] section to NetworkManager.conf to specify connection defaults
Add support for a new section [connection] in NetworkManager.conf.
If the connection leaves an option at "unknown"/"default", we can
support overwriting the value from global configuration.

We also support other sections that are named with "connection"
as a prefix, such as [connection2], [connection-wifi]. This is
to support multiple default values that can be applied depending
on the used device.

I think this has great potential. Only downside is that when
the user looks at a connection value, it will see that it is
unspecified. But the actually used value depends on the device
type and might not be obvious.

https://bugzilla.gnome.org/show_bug.cgi?id=695383
https://bugzilla.redhat.com/show_bug.cgi?id=1164677
2015-06-05 12:38:29 +02:00
Lubomir Rintel
c47c06470a builds: only enable TAP driver for glib >= 2.37.6
No TAP support for previous versions and --tap argument is silently ignored,
confusing the TAP driver.
2015-05-28 12:51:24 +02:00
Lubomir Rintel
6463ce5dd9 tests: use the TAP formatter
The test results in standard format are easily integrated into CI systems.
2015-05-26 13:51:45 +02:00
Beniamino Galvani
a1d76a019e core: capture DNS options from resolv.conf 2015-05-13 17:15:35 +02:00
Thomas Haller
4bdd83127d route-manager/test: fix missing initialization of temporary variables on stack
Up to now, this code was correct. Later we will add another field
to NMPlatformIP4Route which causes the test to operate on
uninitialized data.

Instead of explicitly initializing the field, just clear the whole
struct.
2015-05-13 14:31:05 +02:00
Dan Williams
2abda4bfa5 platform: return link objects from add functions 2015-05-06 16:14:25 -05:00
Thomas Haller
113a4bcb21 test: move some old tests to nm-test-utils.h 2015-05-06 17:23:33 +02:00
Thomas Haller
b22bf15c1d platform: fix root-tests after adding link detection without udev
Co-Authored-By: Lubomir Rintel <lkundrak@v3.sk>

Fixes: 388b7830f3
2015-05-04 18:41:15 +02:00
Thomas Haller
967376b840 core: add nm_utils_monotonic_timestamp_as_boottime() function 2015-04-29 07:32:42 +02:00
Lubomir Rintel
cd2cef9cab utils: match a cloned mac address with a connection that does not specify it
We do the same for the original MAC address.

A device enslaved to a bond it inherits the bond's MAC address. When
NetworkManager tries to assume a connection the generated cloned-mac property
causes a mismatch with the connection that originally brought up the device,
causing the generated connection to be used instead:

  NetworkManager[14190]: <debug> [1424355817.112154] [NetworkManagerUtils.c:1641]
         nm_utils_match_connection(): Connection 'eth2' differs from candidate
         'bond-slave-eth2' in 802-3-ethernet.cloned-mac-address

https://bugzilla.gnome.org/show_bug.cgi?id=744812
2015-04-27 11:33:58 +02:00
Thomas Haller
842ec6163d core: refactor nm_ethernet_address_is_valid() and reject invalid addresses
nm_ethernet_address_is_valid() did not check whether @addr was a valid
address in the first place. It only checked whether the address was not
equal to a few notorious MAC addresses.

At the same time, be more forgiving and accept %NULL as argument.
This fixes an assertion nm_ap_match_in_hash().
2015-04-23 16:38:51 +02:00
Thomas Haller
dbb3b44ca6 core/test: add test for nm_ethernet_address_is_valid() 2015-04-23 16:38:51 +02:00
Thomas Haller
c6529a9d74 platform: add self argument to platform functions
Most nm_platform_*() functions operate on the platform
singleton nm_platform_get(). That made sense because the
NMPlatform instance was mainly to hook fake platform for
testing.

While the implicit argument saved some typing, I think explicit is
better. Especially, because NMPlatform could become a more usable
object then just a hook for testing.

With this change, NMPlatform instances can be used individually, not
only as a singleton instance.

Before this change, the constructor of NMLinuxPlatform could not
call any nm_platform_*() functions because the singleton was not
yet initialized. We could only instantiate an incomplete instance,
register it via nm_platform_setup(), and then complete initialization
via singleton->setup().
With this change, we can create and fully initialize NMPlatform instances
before/without setting them up them as singleton.

Also, currently there is no clear distinction between functions
that operate on the NMPlatform instance, and functions that can
be used stand-alone (e.g. nm_platform_ip4_address_to_string()).
The latter can not be mocked for testing. With this change, the
distinction becomes obvious. That is also useful because it becomes
clearer which functions make use of the platform cache and which not.

Inside nm-linux-platform.c, continue the pattern that the
self instance is named @platform. That makes sense because
its type is NMPlatform, and not NMLinuxPlatform what we
would expect from a paramter named @self.

This is a major diff that causes some pain when rebasing. Try
to rebase to the parent commit of this commit as a first step.
Then rebase on top of this commit using merge-strategy "ours".
2015-04-21 17:51:34 +02:00
Thomas Haller
2117bef864 device: use NMDeviceCapabilities enum for device capabilities 2015-04-18 21:41:40 +02:00
Thomas Haller
bd0c44c1cf route-manager/test: add variations to test code 2015-04-08 14:50:43 +02:00
Thomas Haller
62c652c352 route-manager: refactor route-manager and route_sync()
Refactor the implementation of nm_route_manager_ip4_route_sync()
and nm_route_manager_ip6_route_sync().

- merge the implementations for IPv4 and IPv6.

- pre-sort the routes and iterate them in a way that we don't
  need to lookup a route in other lists. Do this by iterating
  two sorted lists at a time in a merge-sort way.
  The runtime complexity of sync is now O(n*ln(n)).

- previously, the algorithm would merge routes it found in platform
  to priv->ipx_routes. That was wrong, because then we loose the
  information which routes we wanted to configure internally and which
  are present externally.
  Instead, priv->ipx_routes now contains all the routes that were
  explicitly configured via sync(). Hence, it knows what should be
  configured (@ipx_routes) and can compare to what is configured
  (@plat_routes).

https://bugzilla.gnome.org/show_bug.cgi?id=740064
2015-04-08 14:50:43 +02:00
Thomas Haller
e65639bde9 util: add nm_utils_array_remove_at_indexes() function 2015-04-08 14:39:17 +02:00
Thomas Haller
57453189e0 test: add option in nmtst_platform_ip4_routes_equal() to ignore ordering
Same for nmtst_platform_ip6_routes_equal().

It's useful to check for equal routes ignoring the ordering.
2015-04-08 14:39:16 +02:00
Thomas Haller
ba8ce3bbe5 route-manager/test: check for exact expected error message 2015-04-08 14:39:16 +02:00
Thomas Haller
5fd3827e49 route-manager/test: fix usage of g_assert_expect_message()
Tests that use g_assert_expect_message() must initialize with
nmtst_init_assert_logging().

Otherwise, the caller can change the logging level via
  NMTST_DEBUG=log-level=DEBUG,log-domains=DEFAULT
which breaks the assertions.

nmtst_init_assert_logging() allows the caller to turn of
checking of assertions via
  NMTST_DEBUG=log-level=DEBUG,log-domains=DEFAULT,no-expect-message

Also, don't use g_message() in platform tests otherwise the test fail
because nmtst now sets g_log_set_always_fatal().
2015-04-08 14:39:16 +02:00
Thomas Haller
24288f713a platform/test: split initialization of platform tests out
test-route-manager soon wants a different initialization
2015-04-08 14:39:16 +02:00
Thomas Haller
b6d3b98655 test: setup logging during nmtst_init_assert_logging()
Before, when having a test with nmtst_init_assert_logging(),
the caller was expected to setup logging separately according
to the log level that the test asserts against.

Since 5e74891b58, the logging
level can be reset via NMTST_DEBUG also for tests that
assert logging. In this case, it would be useful, if the test
would not overwrite the logging level that is set externally
via NMTST_DEBUG.

Instead, let the test pass the logging configuration to
nmtst_init_assert_logging(), and nmtst will setup logging
-- either according to NMTST_DEBUG or as passed in.

This way, setting the log level works also for no-expect-message
tests:

  NMTST_DEBUG="debug,no-expect-message,log-level=TRACE" $TEST
2015-04-08 14:39:16 +02:00
Lubomir Rintel
4a05869557 platform: don't wait for udev device initializaton if there's no udev
There's no udev running in containers, it only starts if /sys is writable. If a
hardware device is added to the container's namespace NM would not announce it.

This also removes the software link special case -- the software links will now
wait for udev initialization (in case udev is there) as well. There's no reason
to treat them differently anymore. This makes it possible to use udev properties
of the software links.

https://bugzilla.gnome.org/show_bug.cgi?id=740526
2015-03-23 15:13:02 +01:00
Thomas Haller
e82293ebf6 libnm: move _nm_utils_uuid_generate_from_strings() from src/ to libnm-core/ 2015-03-12 18:12:26 +01:00
Thomas Haller
67510e323a trivial: rename nm_utils_uuid_generate_from_strings() to _nm_utils_uuid_generate_from_strings() 2015-03-12 18:12:26 +01:00
Thomas Haller
c5d23737fd libnm: move _nm_utils_ascii_str_to_int64() from src/ to libnm-core/ 2015-03-12 18:12:26 +01:00
Thomas Haller
093f6d477b trivial: rename nm_utils_ascii_str_to_int64() to _nm_utils_ascii_str_to_int64() 2015-03-12 18:12:26 +01:00
Thomas Haller
ea0d0b3086 route-manager/build: fix out-of-tree builds for route-manager tests
Fixes: 0659a67c8f
2015-02-27 19:36:43 +01:00
Lubomir Rintel
f981407a02 core: pass ifindex as parameter to nm_ip6_config_new() 2015-02-27 16:50:09 +01:00
Dan Williams
84f54f0a5f core: pass ifindex as parameter to nm_ip4_config_new() 2015-02-27 16:50:09 +01:00
Lubomir Rintel
0659a67c8f route-manager: add test 2015-02-27 16:48:28 +01:00
Lubomir Rintel
52711b5d89 ip6-config: keep track of ifindex
No functional change, a cosmetic thing for now.

We want it set before any routes are added and ensure routes have a valid
ifindex before we pass it to the platform.

In a future NMRouteManager will need to look up the route for a device in
its cache thus we'll need to make sure routes passed to the it have an
appropriate ifindex set.
2015-02-27 16:48:27 +01:00
Lubomir Rintel
747292a4c3 ip4-config: keep track of ifindex
No functional change, a cosmetic thing for now.

We want it set before any routes are added and ensure routes have a valid
ifindex before we pass it to the platform.

In a future NMRouteManager will need to look up the route for a device in
its cache thus we'll need to make sure routes passed to the it have an
appropriate ifindex set.
2015-02-27 16:48:27 +01:00
Thomas Haller
3bcc5e4bd0 core: add nm_match_spec_split() function
There are currently three device spec properties: 'main.ignore-carrier',
'main.no-auto-default' and 'keyfile.unmanaged-devices'.

The first two, called g_key_file_parse_value_as_string() to split
the string into individual device specs. This uses ',' as separator
and supports escaping using '\\'.

'keyfile.unmanaged-devices' is split using ',' or ';' as separator
without supporting escaping.

Add a new function nm_match_spec_split(), to unify these two behaviors
and support both formats. That is, both previous formats are mostly
supported, but obviously there are some behavioral changes if the string
contains one of '\\', ',', or ';'.

nm_match_spec_split() is copied from glibs g_key_file_parse_value_as_string()
and adjusted.
2015-02-24 10:35:24 +01:00
Thomas Haller
5c2e1afd1b core: support "except:" spec to negate match
Extend nm_match_spec_*() to support an "except:" prefix to negate
the result of a match. "except:" only works when followed by
an exact match type, for example "except:interface-name:vboxnet0",
but not "except:vboxnet0".

A matching "except:" spec always wins, regardless of other positive
matchings.
2015-02-24 10:35:24 +01:00
Thomas Haller
2b518538be core: rework matching of nm_match_spec()
This includes several changes how to match device specs:

- matching the interface name is no longer case-insenstive as
  interface names themselves are case-sensitive.

- Now we skip patterns that start with "mac:" or "s390-subchannels:"
  for comparing interface names. Previously a spec "mac:1" would have
  matched an interface named "mac:1", now it doesn't.
  To match such an interface, you would have to specify
  "interface-name:mac:1".

- previously, a pattern "a" would have matched an interface
  named "interface-name:a", now it doesn't. Since valid interface
  name (in the kernel) can be at most 15 characters long, this is
  however no problem.

- if the spec has the prefix "interface-name:", we support
  simple globbing using GPatternSpec. Globbing without exact
  spec type will still not match "vboxnet*" -- with the exception
  of "*".
  You can disable globbing by putting an '=' immediately
  after the ':'.
     (a) "interface-name:em1"  | matches "em1"
     (b) "interface-name:em*"  | matches "em", "em1", "em2", etc.
     (c) "interface-name:em\*" | matches "em\", "em\1", etc.
     (d) "interface-name:=em*" | matches "em*"
     (e) "em*"                 | matches "em*"
2015-02-24 10:35:24 +01:00
Thomas Haller
9080ad696d core/test: add test for nm_match_spec() 2015-02-24 09:26:50 +01:00
Thomas Haller
5040a8a851 config/tests: inject NMDBusManager for tests in NMDevice stub
We don't need the bus for the tests and the manager may warn when it
is not available.

  $ (cd src/tests/config/; env -i DBUS_SYSTEM_BUS_ADDRESS=meow ./test-config)

  /config/parse-error: OK
  /config/no-auto-default: NetworkManager-Message: <info>  Could not connect to the system bus; only the private D-Bus socket will be available.
  /bin/sh: line 5: 29997 Trace/breakpoint trap   ${dir}$tst
  FAIL: test-config

This reverts commit 6994454461 for the
most part. It's not sufficient to disable logging warnings. Creating
a DBus Manager might affect the system in undesired ways.
2015-02-16 17:54:43 +01:00