Commit graph

1050 commits

Author SHA1 Message Date
Thomas Haller
ac60b0ce60 platform: move link accessors to NMPlatform base class
and refactor NMFakePlatform to also track links via NMPCache.

For one, now NMFakePlatform also tests NMPCache, increasing the
coverage of what we care about.

Also, all our NMPlatform implementations now use NMPObject and NMPCache.
That means, we can expose those as part of the public API. Which is
great, because callers can keep a reference to the NMPObject object
and make use of generic functions like nmp_object_to_string().
2017-07-05 18:37:39 +02:00
Thomas Haller
71cf60e852 platform: refactor fake platform to use NMPCache for addresses
And move some code from NMLinuxPlatform to NMPlatform, where it belongs.

The advantage is that we reuse (and test!) the NMPCache implementation for
tracking addresses.

Also, we now always expose proper NMPObjects from both linux and fake
platform.

For example,

  obj = NMP_OBJECT_UP_CAST (nm_platform_ip4_address_get (...));

will work as expected. Also, the caller is now by NMPlatform API
allowed to take and keep a reference to the returned objects.
2017-07-05 18:37:39 +02:00
Thomas Haller
8b3b148fda platform/trivial: rename cache-id-type indexes 2017-07-05 18:37:39 +02:00
Thomas Haller
17f02318ad platform: drop separate index for visible objects
Routes and addresses don't implement cmd_obj_is_visible(),
hence they are always visible, and NMP_CACHE_ID_TYPE_OBJECT_TYPE_VISIBLE_ONLY
is identical to NMP_CACHE_ID_TYPE_OBJECT_TYPE.

Only link objects can be alive but invisible. Still, drop the index
for looking up visible links entirely. Let callers do the filtering,
if they care.
2017-07-05 18:37:39 +02:00
Thomas Haller
beb0b9b1ad platform: reduce number of route indexes
Maintaining an index is expensive.Not so much in term of runtime, but
in term of memory.

Drop some indexes, and require the caller to use a more broad index (and
filter out unwanted elements).

Dropped:

 - can no longer lookup visible default-routes by ifindex.
   If you care about default-routes, lookup all and search for the
   desired ifindex. The overall number of default-routes is expected
   to be small.
   We drop NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_BY_IFINDEX_WITH_DEFAULT
   entirely.

 - no longer have a separate index for non-default routes. We
   expect that the most routes are non-default routes. So, don't
   have an index without default-routes, instead let the caller
   just lookup all routes, and reject default-routes themself.
   We keep NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_BY_DEFAULT, but it
   now no longer tracks non-default routes.

This drops 1 out of 6 route indexes, and modifes another one, so
that we expect that there are almost no entires tracked by it.
2017-07-05 18:37:39 +02:00
Thomas Haller
35f52aafc1 platform: drop nm_platform_ip6_route_get_all()
We no longer need a full clone of routes. The only remaining uses
are in test code. Rework it.
2017-07-05 18:37:39 +02:00
Thomas Haller
aeaa1b3b98 platform: refactor nm_dedup_multi_objs_to_ptr_array_head()
by moving the core functionality to "nm-dedup-multi.c".

As the ref-counting mechanism now is part of "nm-dedup-multi.c",
this works better and is reusable outside of platform.
2017-07-05 18:37:39 +02:00
Thomas Haller
28340588d9 core: remove NMDedupMultiBox object and track NMDedupMultiObj instances directly
Implement the reference counting of NMPObject as part of
NMDedupMultiObj and get rid of NMDedupMultiBox.

With this change, the NMPObject is aware in which NMDedupMultiIndex
instance it is tracked.

- this saves an additional GSlice allocation for the NMDedupMultiBox.

- it is immediately known, whether an NMPObject is tracked by a
  certain NMDedupMultiIndex or not. This saves an additional hash
  lookup.

- previously, when all idx-types cease to reference an NMDedupMultiObj
  instance, it was removed. Now, a tracked objects stays in the
  NMDedupMultiIndex until it's last reference is deleted. This possibly
  extends the lifetime of the object and we may reuse it better.

- it is no longer possible to add one object to more then one
  NMDedupMultiIndex instance. As we anyway want to have only one
  instance to deduplicate the objects, this is fine.

- the ref-counting implementation is now part of NMDedupMultiObj.
  Previously, NMDedupMultiIndex could also track objects that were
  not ref-counted. Hoever, the object anyway *must* implement the
  NMDedupMultiObj API, so this flexibility is unneeded and was not
  used.

- a downside is, that NMPObject grows by one pointer size, even if
  it isn't tracked in the NMDedupMultiIndex. But we really want to
  put all objects into the index for sharing and deduplication. So
  this downside should be acceptable. Still, code like
  nmp_object_stackinit*() needs to handle a larger object.
2017-07-05 18:37:39 +02:00
Thomas Haller
667c50f5d9 core: avoid cloning platform routes but iterate the cache directly 2017-07-05 18:37:39 +02:00
Thomas Haller
c9cd6d9954 platform: track routes in NMFakePlatform via NMPCache
NMPlatform's cache should be directly accessible to the users,
at least the NMPLookup part and the fact that the cache contains
ref-counted, immutable NMPObjects.

This allows users to inspect the cache with zero overhead. Meaning,
they can obtain an NMDedupMultiHeadEntry and iterate the objects
themself. It also means, the are free to take and keep references
of the NMPObject instances (of course, without modifying them!).

NMFakePlatform will use the very same cache. The fake platform should
only differ when modifying the objects.

Another reason why this makes sense is because NMFakePlatform is for one
a test-stup but also tests behavior of platform itself. Using a separate
internal implementation for the caching is a pointless excecise, because
only the real NMPCache's implementation really matters for production.
So, either NMFakePlatform behaves idential, or it is buggy. Reuse it.

Port fake platform's tracking of routes to NMPCache and move duplicate
code from NMLinuxPlatform to the base class.

This commit only ports IP routes, eventually also addresses and links
should be tracked via the NMPCache instance.
2017-07-05 18:37:39 +02:00
Thomas Haller
16aefdd865 platform: expose index lookup for objects in public API 2017-07-05 18:37:39 +02:00
Thomas Haller
c5af191dbf platform: expose emit-signal function from platform
It will be used by NMFakePlatform too.
2017-07-05 18:37:39 +02:00
Thomas Haller
e160928b9e platform: move the NMPCache from linux platform to NMPlatform
We want to expose the NMPLookup and NMDedupMultiHeadEntry to the users
of NMPlatform, so that they can iterate the cache directly.

That means, NMPCache becames an integral part of NMPlatform's API
and must also be implemented by NMFakePlatform.
2017-07-05 18:37:39 +02:00
Thomas Haller
485551286c platform: add use-udev property for NMPlatform
We want to move the multi_idx from NMLinuxPlatform to NMPlatform,
so that it can be used by NMFakePlatform as well. For that, we need
to know whether NMPlatform will use udev or not. Add a constrctor
property.
2017-07-05 18:37:39 +02:00
Thomas Haller
55e66cc7e6 platform: implement hash function for NMPlatformLnk types 2017-07-05 18:37:39 +02:00
Thomas Haller
d2f856fb95 platform: fix nmp_object_hash() to include object type
NMPlatformLnkMacvtap is a typedef of NMPlatformLnkMacvlan, hence, their
plobj implementation is idential. nmp_object_equal() already correctly
compares the object type, so we should hash it too.
2017-07-05 18:37:39 +02:00
Thomas Haller
35502807b5 platform: merge NMP_CACHE_ID_TYPE_ROUTES_BY_DESTINATION* index
In this case, not much is saved, because previously IPv4 and IPv6
routes had completely distinct indexes.
2017-07-05 18:37:38 +02:00
Thomas Haller
6324b779b2 platform: merge NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_*_DEFAULT indexes
Maintaining an index is expensive. We can merge indexes that
are strictly distinct, because one index can just partition the
objects into distinct sets.
2017-07-05 18:37:38 +02:00
Thomas Haller
9440eefb6d platform: use NMDedupMultiIndex for routes in NMPCache
Rework platform object cache to use NMDedupMultiIndex.

Already previously, NMPCache used NMMultiIndex and had thus
O(1) for most operations. What is new is:

- Contrary to NMMultiIndex, NMDedupMultiIndex preserves the order of
  the cached items. That is crucial to handle routes properly as kernel
  will replace the first matching route based on network/plen/metric
  properties. See related bug rh#1337855.
  Without tracking the order of routes as they are exposed
  by kernel, we cannot properly maintain the route cache.

- All NMPObject instances are now treated immutable, refcounted
  and get de-duplicated via NMDedupMultiIndex. This allows
  to have a global NMDedupMultiIndex that can be shared with
  NMIP4Config and NMRouteManager. It also allows to share the
  objects themselves.
  Immutable objects are so much nicer. We can get rid of the
  update pre-hook callback, which was required previously because
  we would mutate the object inplace. Now, we can just update
  the cache, and compare obj_old and obj_new after the fact.

- NMMultiIndex was treated as an internal of NMPCache. On the other
  hand, NMDedupMultiIndex exposes NMDedupMultiHeadEntry, which is
  basically an object that allows to iterate over all related
  objects. That means, we can now lookup objects in the cache
  and give the NMDedupMultiHeadEntry instance to the caller,
  which then can iterate the list on it's own -- without need
  for copying anything.
  Currently, at various places we still create copies of lookup
  results. That can be improved later.

The ability to share NMPObject instances should enable us to
significantly improve performance and scale with large number
of routes.

Of course there is a memory overhead of having an index for each list
entry. Each NMPObject may also require an NMDedupMultiEntry,
NMDedupMultiHeadEntry, and NMDedupMultiBox item, which are tracked
in a GHashTable. Optimally, one NMDedupMultiHeadEntry is the head
for multiple objects, and NMDedupMultiBox is able to deduplicate several
NMPObjects, so that there is a net saving.
Also, each object type has several indexes of type NMPCacheIdType.
So, worst case an NMPlatformIP4Route in the platform cache is tracked
by 8 NMPCacheIdType indexes, for each we require a NMDedupMultiEntry,
plus the shared NMDedupMultiHeadEntry. The NMDedupMultiBox instance
is shared between the 8 indexes (and possibly other).
2017-07-05 18:37:38 +02:00
Thomas Haller
3edf2bff3d platform: fix lookup of all routes unrestricted to an ifindex
Need to use the right NMPCacheIdType when looking up routes
across all ifindexes.

Fixes: 8f9dac01ac
2017-07-05 14:22:10 +02:00
Thomas Haller
0b060d9bc5 platform/trivial: rename variable 2017-07-05 14:22:10 +02:00
Thomas Haller
8822c45453 platform: use NM_SET_OUT() macro 2017-07-05 14:22:10 +02:00
Thomas Haller
89385bd968 core: pass NMDedupMultiIndex instance to NMIP4Config and other
NMIP4Config, NMIP6Config, and NMPlatform shall share one
NMDedupMultiIndex instance.

For that, pass an NMDedupMultiIndex instance to NMPlatform and NMNetns.
NMNetns than passes it on to NMDevice, NMDhcpClient, NMIP4Config and NMIP6Config.
So currently NMNetns is the access point to the shared NMDedupMultiIndex
instance, and it gets it from it's NMPlatform instance.

The NMDedupMultiIndex instance is really a singleton, we don't want
multiple instances of it. However, for testing, instead of adding a
singleton instance, pass the instance explicitly around.
2017-07-05 14:22:10 +02:00
Thomas Haller
6d9c3eab38 platform: let NMPObject implement NMDedupIndexObj 2017-07-05 14:22:10 +02:00
Thomas Haller
b8bc80bcdb all: add base object type in "nm-obj.h"
Platform has it's own, simple implementation of object types:
NMPObject. Extract a base type and move it to "shared/nm-utils/nm-obj.h"
so it can be reused.

The base type is trival, but it allows us to implement other objects
which are compatible with NMPObjects. Currently there is no API for generic
NMObjBaseInst type, so compatible in this case only means, that they
can be used in the same context (see example below).
The only thing that you can do with a NMObjBaseInst is check it's
NMObjBaseClass.

Incidentally, NMObjBaseInst is also made compatible to GTypeInstance.
It means, an NMObjBaseInst is not necessarily a valid GTypeInstance (like NMPObject
is not), but it could be implemented as such.

For example, you could do:

    if (NMP_CLASS_IS_VALID ((NMPClass *) obj->klass)) {
        /* is an NMPObject */
    } else if (G_TYPE_CHECK_INSTANCE_TYPE (obj, NM_TYPE_SOMETHING)) {
        /* it a NMSometing GType */
    } else {
        /* something else? */
    }

The reason why NMPObject is not implemented as proper GTypeInstance is
because it would require us to register a GType (like
g_type_register_fundamental). However, then the NMPClass struct can
no longer be const and immutable memory. But we could.

NMObjBaseInst may or may not be a GTypeInstance. In a sense, it's
a base type of GTypeInstance and all our objects should be based
on it (optionally, they we may make them valid GTypes too).
2017-07-05 14:22:10 +02:00
Thomas Haller
3f76b5b7eb core: use NM_HASH_COMBINE() function 2017-07-05 14:22:10 +02:00
Thomas Haller
b002357f5f platform: fix nm_platform_lnk_macvlan_cmp() to consider "tap" field 2017-07-05 14:22:10 +02:00
Thomas Haller
b8707cba3c platform/tests: minor fix in _wait_for_ipv6_addr_non_tentative()
For better or worse, there is a platform argument. Use it instead
of the singleton.
2017-05-31 11:01:52 +02:00
Thomas Haller
d6aae6af72 platform/tests: reorder wait-loop in test_ip6_route_options()
- no need to call nm_platform_process_events() after
  nmtstp_wait_for_signal(). The latter processes all events
  that are pending.
- with addr_n number of addresses, we still only want to wait
  a maximum time, not for each addresss individually. Basically,
  the for-loop must be inside NMTST_WAIT(), not the other way around.
2017-05-31 10:46:43 +02:00
Thomas Haller
07751b444b platform/tests: make timeout_ms argument for nmtstp_wait_for_signal() signed
Having an unsigned "guint timeout_ms" argument is very inconvenient, because

    nmtstp_wait_for_signal (NM_PLATFORM_GET (), end_time - now_time);

might easily be negative. In such a case, the correct behavior
is to wait not at all.
2017-05-31 10:46:43 +02:00
Thomas Haller
af9c474844 platform/tests: change nmtstp_wait_for_signal() to wait with zero timeout
The previous behavior, of treating timeout_ms as *no timeout*, makes
no sense. At least not for unit tests. If you have a really long timeout,
then set it. "0" should really mean to schedule a zero timeout.
2017-05-31 10:46:43 +02:00
Francesco Giudici
21a941d40b platform/tests: fix test_ip6_route_options
when adding a route with RTA_PREFSRC some kernel versions will reject
the request if the specified source address is still tentative: be sure
that the just added addresses are no more tentative before adding the
routes.
2017-05-30 19:00:54 +02:00
Thomas Haller
d3c71ce4da platform/tests: use nm_platform_link_veth_add() to create veth pair in test 2017-05-27 23:16:56 +02:00
Thomas Haller
6ab2288c28 platform: add nm_platform_link_veth_add() to create VETH links 2017-05-27 23:16:56 +02:00
Thomas Haller
2c4d9f66ae platform/tests: recreate test environment for each route test
Use nmtstp_env1_add_test_func*() to setup and teardown a new
interface for each test.
2017-05-27 23:16:56 +02:00
Thomas Haller
a367361bc8 platform/tests: refactor test_ip6_route_options() to make it extendable
Have it suitable for multiple scenarios.
2017-05-27 23:16:56 +02:00
Thomas Haller
0f905a0b88 platform/tests: move test fixture "env1" from test-address.c to test-common.h
nmtstp_env1_add_test_func() allows to register test functions in a
particular test environment ("env1", for lack of a better name).

It will be reused for "test-route.c"
2017-05-27 23:16:56 +02:00
Thomas Haller
d1b951a7e5 platform: remove plen argument for IPv6 address ID
The prefix length is not part of the ID for IPv6 address. Remove
it from nmp_object_stackinit_id_ip6_address().
2017-05-27 11:38:38 +02:00
Beniamino Galvani
31656a066b core: add configuration flag to choose slaves activation order
Commits 39d0559d9a ("platform: sort links by name instead of
ifindex") and 529a0a1a7f ("manager: sort slaves to be autoconnected
by device name") changed the order of activation of slaves. Introduce
a system-wide configuration property to preserve the old behavior.

https://bugzilla.redhat.com/show_bug.cgi?id=1452585
2017-05-24 15:56:15 +02:00
Francesco Giudici
23bc781063 all/trivial: fix few comment typos 2017-05-15 15:52:21 +02:00
Nikolay Martynov
58f7813283 platform: ignore RTM_GETLINK messages sent by wireless extentions
We listen to all RTM_GETLINK messages to get updates on interfaces statuses.
Unfortunately wireless code in the kernel sends those messages with wireless information included
and all other information excluded. When we receive such message we wipe out our valid cached entry
with new object that is almost empty because netlink message didn't contain any information.

Solution to this is to check that incoming message contains MTU field: this field is always
set for complete messages about interfaces and is not set by wireless code.

Signed-off-by: Nikolay Martynov <mar.kolya@gmail.com>

https://github.com/NetworkManager/NetworkManager/pull/17
2017-05-11 17:41:10 +02:00
Beniamino Galvani
e6ff7f211d platform: fix double initialization
(cherry picked from commit 708ee92c29)
2017-05-08 15:05:01 +02:00
Beniamino Galvani
1d08391ed1 all: fix typo 'entires' -> 'entries'
(cherry picked from commit a4cbfe6f0a)
2017-05-05 19:16:39 +02:00
Thomas Haller
8ac1bf76bd core: move NMIPAddr to nm-core-utils.h
(cherry picked from commit 67da0a28db)
2017-04-27 17:21:33 +02:00
Beniamino Galvani
2511e27e76 platform: detect SR-IOV support and allow changing the number of VFs
(cherry picked from commit 0a7694cf81)
2017-04-18 23:28:59 +02:00
Thomas Haller
c2297fb66c core: enable "log-with-ptr" by default for platform and route-manager
Arguably, we currently only have one instance of NMPlatform,
NMRouteManager, NMDefaultRouteManager -- the one owned by the
NMNetns singleton.

Hence, all these instances we create with "log-with-ptr" set explicitly
to false.

In the future we want to support namespaces, and it will be be common to
have multiple instances. For that we have "log-with-ptr" so we are able
to disambiguiate the logging.

Change the default to TRUE because it makes more sense. It has currently
no effect as the default is never used.

(cherry picked from commit 41148caba8)
2017-04-18 15:53:11 +02:00
Thomas Haller
d37b9d79bc core: add NMNetns to bundle platform and route managers
NMPlatform, NMRouteManager and NMDefaultRouteManager are singletons
instances. Users of those are for example NMDevice, which registers
to GObject signals of both NMPlatform and NMRouteManager.

Hence, as NMDevice:dispose() disconnects the signal handlers, it must
ensure that those singleton instances live longer then the NMDevice
instance. That is usually accomplished by having users of singleton
instances own a reference to those instances.
For NMDevice that effectively means that it shall own a reference to
several singletons.

NMPlatform, NMRouteManager, and NMDefaultRouteManager are all
per-namespace. In general it doesn't make sense to have more then
one instances of these per name space. Nnote that currently we don't
support multiple namespaces yet. If we will ever support multiple
namespaces, then a NMDevice would have a reference to all of these
manager instances. Hence, introduce a new class NMNetns which bundles
them together.

(cherry picked from commit 0af2f5c28b)
2017-04-18 15:53:11 +02:00
Lubomir Rintel
fcad4fba16 platform: fix a typo
(cherry picked from commit c76ee5883d)
2017-04-18 09:43:43 +02:00
Thomas Haller
be19ec0739 core: ignore host part when comparing routes for route-manager
(cherry picked from commit b78562570a)
2017-04-15 00:37:22 +02:00
Thomas Haller
ae8d98391a platform: only consider net part of routes for route cache's ID
Routes with a non-zero host part are not allowed by kernel and
don't really exist. We didn't reject such routes in users configuration,
so various part of NM allow such routes. NM should silently strip
the host part.

Extend the cache's route ID to clear the host part too.

Note that NM's handling of routes is fundamentally flawed, as
for kernels routes don't have an "id" (or rather: all properties
of a route are part of it's ID, not only the family,ifindex,
network/plen and metric tuple (see related bug rh#1337855).

(cherry picked from commit 57b0dce083)
2017-04-15 00:37:22 +02:00