Commit graph

174 commits

Author SHA1 Message Date
Beniamino Galvani
02ea74c920 core: signal parent-active only when the parent AC is activated
The parent-active signal is used by the manager to determine when the
parent active-connection is ready and a connection that depend on it
can proceed.

The AC state could transition from ACTIVATING directly to
DEACTIVATING; in such case we should not emit the signal but instead
just stop watching the parent AC.

Fixes: 6e382ea91d ('active-connection: add parent active connection tracking')
https://bugzilla.redhat.com/show_bug.cgi?id=1778073
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/510
2020-05-19 21:40:51 +02:00
Thomas Haller
44fed3c340 core: avoid assertion failure in _settings_connection_flags_changed() without device
It seems not unexpected, that we get a flags-changed notification while
having no device. Handle it gracefully and avoid the assertion failure.

   #0  _g_log_abort (breakpoint=breakpoint@entry=1) at gmessages.c:583
   #1  g_logv (log_domain=0x55f3c86f0262 "NetworkManager", log_level=G_LOG_LEVEL_CRITICAL, format=<optimized out>, args=args@entry=0x7ffcbf88f1c0) at gmessages.c:1391
   #2  g_log (log_domain=log_domain@entry=0x55f3c86f0262 "NetworkManager", log_level=log_level@entry=G_LOG_LEVEL_CRITICAL, format=format@entry=0x7f21e99adb27 "%s: assertion '%s' failed") at gmessages.c:1432
   #3  g_return_if_fail_warning (log_domain=log_domain@entry=0x55f3c86f0262 "NetworkManager", pretty_function=pretty_function@entry=0x55f3c875f290 <__func__.53083> "nm_device_reapply", expression=expression@entry=0x55f3c8752507 "NM_IS_DEVICE (self)") at gmessages.c:2809
   #4  nm_device_reapply (self=0x0, connection=connection@entry=0x55f3caab4e60, error=error@entry=0x7ffcbf88f308) at src/devices/nm-device.c:12107
   #5  _settings_connection_flags_changed (settings_connection=<optimized out>, self=0x55f3caabca70 [NMActRequest]) at src/nm-active-connection.c:960
   #9  <emit signal ??? on instance 0x55f3caaaf530 [NMSettingsConnection]> (instance=instance@entry=0x55f3caaaf530, signal_id=<optimized out>, detail=detail@entry=0) at gsignal.c:3447
   #6  g_closure_invoke (closure=0x55f3caa4c160, return_value=return_value@entry=0x0, n_param_values=1, param_values=param_values@entry=0x7ffcbf88f520, invocation_hint=invocation_hint@entry=0x7ffcbf88f4c0) at gclosure.c:804
   #7  signal_emit_unlocked_R (node=node@entry=0x55f3ca9dcf90, detail=detail@entry=0, instance=instance@entry=0x55f3caaaf530, emission_return=emission_return@entry=0x0, instance_and_params=instance_and_params@entry=0x7ffcbf88f520) at gsignal.c:3635
   #8  g_signal_emit_valist (instance=<optimized out>, signal_id=<optimized out>, detail=<optimized out>, var_args=var_args@entry=0x7ffcbf88f6a0) at gsignal.c:3391
   #10 nm_settings_connection_set_flags_full (self=self@entry=0x55f3caaaf530 [NMSettingsConnection], mask=<optimized out>, value=<optimized out>) at src/settings/nm-settings-connection.c:2025
   #11 _connection_changed_process_all_dirty (update_reason=(NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS), sett_mask=<optimized out>, sett_flags=<optimized out>, connection=0x55f3caab4f80, sett_conn_entry=<optimized out>, self=0x55f3ca99c000 [NMSettings]) at src/settings/nm-settings.c:1099
   #12 _connection_changed_process_all_dirty (update_reason=(NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS), override_sett_flags=1, sett_mask=_NM_SETTINGS_CONNECTION_INT_FLAGS_PERSISTENT_MASK, sett_flags=<optimized out>, allow_add_to_no_auto_default=0, sett_conn_entry=<optimized out>, self=0x55f3ca99c000 [NMSettings]) at src/settings/nm-settings.c:1284
   #13 _connection_changed_process_all_dirty (self=self@entry=0x55f3ca99c000 [NMSettings], allow_add_to_no_auto_default=allow_add_to_no_auto_default@entry=0, sett_flags=sett_flags@entry=NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, sett_mask=sett_mask@entry=NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, override_sett_flags=override_sett_flags@entry=1, update_reason=update_reason@entry=(NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS)) at src/settings/nm-settings.c:1304
   #14 _plugin_connections_reload (self=self@entry=0x55f3ca99c000 [NMSettings]) at src/settings/nm-settings.c:1417
   #15 impl_settings_reload_connections (obj=0x55f3ca99c000 [NMSettings], interface_info=<optimized out>, method_info=<optimized out>, connection=<optimized out>, sender=<optimized out>, invocation=0x7f21d000c100 [GDBusMethodInvocation], parameters=0x55f3ca9e1f20) at src/settings/nm-settings.c:2822
   ...

https://bugzilla.redhat.com/show_bug.cgi?id=1816067
2020-03-23 13:31:09 +01:00
Thomas Haller
073994ca42 all: use nm_clear_g_free() instead of g_clear_pointer()
I think it's preferable to use nm_clear_g_free() instead of
g_clear_pointer(, g_free). The reasons are not very strong,
but I think it is overall preferable to have a shorthand for this
frequently used functionality.

   sed 's/\<g_clear_pointer *(\([^;]*\), *\(g_free\) *)/nm_clear_g_free (\1)/g' $(git grep -l g_clear_pointer) -i
2020-03-23 11:05:34 +01:00
Thomas Haller
de62da297e all: drop explicit casts from _GET_PRIVATE() macro calls
The _GET_PRIVATE() macros are all implemented based on
_NM_GET_PRIVATE(). That macro tries to be more type safe and uses
_Generic() to do the right thing. Explicitly casting is not only
unnecessary, it defeats these (static) type checks.

Don't do that.
2020-02-14 11:04:46 +01:00
Thomas Haller
cd31437024 shared: drop _STATIC variant of macros that define functions
Several macros are used to define function. They had a "_STATIC" variant,
to define the function as static.

I think those macros should not try to abstract entirely what they do.
They should not accept the function scope as argument (or have two
variants per scope). This also because it might make sense to add
additional __attribute__(()) to the function. That only works, if
the macro does not pretend to *not* define a plain function.

Instead, embrace what the function does and let the users place the
function scope as they see fit.

This also follows what is already done with

    static NM_CACHED_QUARK_FCN ("autoconnect-root", autoconnect_root_quark)
2020-02-13 17:17:07 +01:00
Thomas Haller
8c23586a77 shared: drop nm_utils_dbus_normalize_object_path() in favor of nm_dbus_path_not_empty()
They do the same thing. Unify and drop one.
2020-02-10 19:11:50 +01:00
Antonio Cardace
1e45865e4f shared: nm-auth-subject: add unix-session type 2019-12-24 10:13:51 +01:00
Antonio Cardace
0f7994328d shared: move nm-dbus-auth-subject to shared/nm-libnm-core-intern
Move it to shared as it's useful for clients as well.

Move and rename nm_dbus_manager_new_auth_subject_from_context() and
nm_dbus_manager_new_auth_subject_from_message() in nm-dbus-manager.c
as they're needed there.
2019-12-24 10:13:51 +01:00
Thomas Haller
10c63f167d core: don't use pointer value for pending action string in active-connection
The pending action gets logged. We should not log plain pointer
values because they may be used to defeat ASLR.

Instead, construct the pending action using the "version_id". This
number is also unique, and suits sufficiently well. With debug logging
you can still grep the log for the corresponding active-connection (and
anyway it's obvious from the context).
2019-10-14 16:37:16 +02:00
Thomas Haller
abff46cacf all: manually drop code comments with file description 2019-10-01 07:50:52 +02:00
Lubomir Rintel
24028a2246 all: SPDX header conversion
$ find * -type f |xargs perl contrib/scripts/spdx.pl
  $ git rm contrib/scripts/spdx.pl
2019-09-10 11:19:56 +02:00
Thomas Haller
d35d3c468a settings: rework tracking settings connections and settings plugins
Completely rework how settings plugin handle connections and how
NMSettings tracks the list of connections.

Previously, settings plugins would return objects of (a subtype of) type
NMSettingsConnection. The NMSettingsConnection was tightly coupled with
the settings plugin. That has a lot of downsides.

Change that. When changing this basic relation how settings connections
are tracked, everything falls appart. That's why this is a huge change.
Also, since I have to largely rewrite the settings plugins, I also
added support for multiple keyfile directories, handle in-memory
connections only by keyfile plugin and (partly) use copy-on-write NMConnection
instances. I don't want to spend effort rewriting large parts while
preserving the old way, that anyway should change. E.g. while rewriting ifcfg-rh,
I don't want to let it handle in-memory connections because that's not right
long-term.

--

If the settings plugins themself create subtypes of NMSettingsConnection
instances, then a lot of knowledge about tracking connections moves
to the plugins.
Just try to follow the code what happend during nm_settings_add_connection().
Note how the logic is spread out:
 - nm_settings_add_connection() calls plugin's add_connection()
 - add_connection() creates a NMSettingsConnection subtype
 - the plugin has to know that it's called during add-connection and
   not emit NM_SETTINGS_PLUGIN_CONNECTION_ADDED signal
 - NMSettings calls claim_connection() which hocks up the new
   NMSettingsConnection instance and configures the instance
   (like calling nm_settings_connection_added()).
This summary does not sound like a lot, but try to follow that code. The logic
is all over the place.

Instead, settings plugins should have a very simple API for adding, modifying,
deleting, loading and reloading connections. All the plugin does is to return a
NMSettingsStorage handle. The storage instance is a handle to identify a profile
in storage (e.g. a particular file). The settings plugin is free to subtype
NMSettingsStorage, but it's not necessary.
There are no more events raised, and the settings plugin implements the small
API in a straightforward manner.
NMSettings now drives all of this. Even NMSettingsConnection has now
very little concern about how it's tracked and delegates only to NMSettings.

This should make settings plugins simpler. Currently settings plugins
are so cumbersome to implement, that we avoid having them. It should not be
like that and it should be easy, beneficial and lightweight to create a new
settings plugin.

Note also how the settings plugins no longer care about duplicate UUIDs.
Duplicated UUIDs are a fact of life and NMSettings must handle them. No
need to overly concern settings plugins with that.

--

NMSettingsConnection is exposed directly on D-Bus (being a subtype of
NMDBusObject) but it was also a GObject type provided by the settings
plugin. Hence, it was not possible to migrate a profile from one plugin to
another.
However that would be useful when one profile does not support a
connection type (like ifcfg-rh not supporting VPN). Currently such
migration is not implemented except for migrating them to/from keyfile's
run directory. The problem is that migrating profiles in general is
complicated but in some cases it is important to do.

For example checkpoint rollback should recreate the profile in the right
settings plugin, not just add it to persistent storage. This is not yet
properly implemented.

--

Previously, both keyfile and ifcfg-rh plugin implemented in-memory (unsaved)
profiles, while ifupdown plugin cannot handle them. That meant duplication of code
and a ifupdown profile could not be modified or made unsaved.
This is now unified and only keyfile plugin handles in-memory profiles (bgo #744711).
Also, NMSettings is aware of such profiles and treats them specially.
In particular, NMSettings drives the migration between persistent and non-persistent
storage.

Note that a settings plugins may create truly generated, in-memory profiles.
The settings plugin is free to generate and persist the profiles in any way it
wishes. But the concept of "unsaved" profiles is now something explicitly handled
by keyfile plugin. Also, these "unsaved" keyfile profiles are persisted to file system
too, to the /run directory. This is great for two reasons: first of all, all
profiles from keyfile storage in fact have a backing file -- even the
unsaved ones. It also means you can create "unsaved" profiles in /run
and load them with `nmcli connection load`, meaning there is a file
based API for creating unsaved profiles.
The other advantage is that these profiles now survive restarting
NetworkManager. It's paramount that restarting the daemon is as
non-disruptive as possible. Persisting unsaved files to /run improves
here significantly.

--

In the past, NMSettingsConnection also implemented NMConnection interface.
That was already changed a while ago and instead users call now
nm_settings_connection_get_connection() to delegate to a
NMSimpleConnection. What however still happened was that the NMConnection
instance gets never swapped but instead the instance was modified with
nm_connection_replace_settings_from_connection(), clear-secrets, etc.
Change that and treat the NMConnection instance immutable. Instead of modifying
it, reference/clone a new instance. This changes that previously when somebody
wanted to keep a reference to an NMConnection, then the profile would be cloned.
Now, it is supposed to be safe to reference the instance directly and everybody
must ensure not to modify the instance. nmtst_connection_assert_unchanging()
should help with that.
The point is that the settings plugins may keep references to the
NMConnection instance, and so does the NMSettingsConnection. We want
to avoid cloning the instances as long as they are the same.
Likewise, the device's applied connection can now also be referenced
instead of cloning it. This is not yet done, and possibly there are
further improvements possible.

--

Also implement multiple keyfile directores /usr/lib, /etc, /run (rh #1674545,
bgo #772414).

It was always the case that multiple files could provide the same UUID
(both in case of keyfile and ifcfg-rh). For keyfile plugin, if a profile in
read-only storage in /usr/lib gets modified, then it gets actually stored in
/etc (or /run, if the profile is unsaved).

--

While at it, make /etc/network/interfaces profiles for ifupdown plugin reloadable.

--

https://bugzilla.gnome.org/show_bug.cgi?id=772414
https://bugzilla.gnome.org/show_bug.cgi?id=744711
https://bugzilla.redhat.com/show_bug.cgi?id=1674545
2019-07-16 19:09:08 +02:00
Thomas Haller
8a8e894f80 core: add and use nm_keep_alive_destroy()
When we are done with a NMKeepAlive instance, we always should do
three things:

  - unset the owner
  - disarm (freeze) the keep-alive
  - give up our reference.

Add and use nm_keep_alive_destroy() that does this.
2019-06-27 13:25:40 +02:00
Thomas Haller
c0e075c902 all: drop emacs file variables from source files
We no longer add these. If you use Emacs, configure it yourself.

Also, due to our "smart-tab" usage the editor anyway does a subpar
job handling our tabs. However, on the upside every user can choose
whatever tab-width he/she prefers. If "smart-tabs" are used properly
(like we do), every tab-width will work.

No manual changes, just ran commands:

    F=($(git grep -l -e '-\*-'))
    sed '1 { /\/\* *-\*-  *[mM]ode.*\*\/$/d }'     -i "${F[@]}"
    sed '1,4 { /^\(#\|--\|dnl\) *-\*- [mM]ode/d }' -i "${F[@]}"

Check remaining lines with:

    git grep -e '-\*-'

The ultimate purpose of this is to cleanup our files and eventually use
SPDX license identifiers. For that, first get rid of the boilerplate lines.
2019-06-11 10:04:00 +02:00
Thomas Haller
8a78493de1 settings: cache keyfile databases for "timestamps" and "seen-bssids"
Only read the keyfile databases once and cache them for the remainder of
the program.

- this avoids the overhead of opening the file over and over again.

- it also avoids the data changing without us expecting it. The state
  files are internal and we don't support changing it outside of
  NetworkManager. So in the base case we read the same data over
  and over. In the worst case, we read different data but are not
  interested in handling the changes.

- only write the file when the content changes or before exiting
  (normally).

- better log what is happening.

- our state files tend to grow as we don't garbage collect old entries.
  Keeping this all in memory might be problematic. However, the right
  solution for this is that we come up with some form of garbage
  collection so that the state files are reaonsably small to begin with.
2019-05-07 16:41:21 +02:00
Thomas Haller
284ac92eee shared: build helper "libnm-libnm-core-{intern|aux}.la" library for libnm-core
"libnm-core" implements common functionality for "NetworkManager" and
"libnm".

Note that clients like "nmcli" cannot access the internal API provided
by "libnm-core". So, if nmcli wants to do something that is also done by
"libnm-core", , "libnm", or "NetworkManager", the code would have to be
duplicated.

Instead, such code can be in "libnm-libnm-core-{intern|aux}.la".
Note that:

  0) "libnm-libnm-core-intern.la" is used by libnm-core itsself.
     On the other hand, "libnm-libnm-core-aux.la" is not used by
     libnm-core, but provides utilities on top of it.

  1) they both extend "libnm-core" with utlities that are not public
     API of libnm itself. Maybe part of the code should one day become
     public API of libnm. On the other hand, this is code for which
     we may not want to commit to a stable interface or which we
     don't want to provide as part of the API.

  2) "libnm-libnm-core-intern.la" is statically linked by "libnm-core"
     and thus directly available to "libnm" and "NetworkManager".
     On the other hand, "libnm-libnm-core-aux.la" may be used by "libnm"
     and "NetworkManager".
     Both libraries may be statically linked by libnm clients (like
     nmcli).

  3) it must only use glib, libnm-glib-aux.la, and the public API
     of libnm-core.
     This is important: it must not use "libnm-core/nm-core-internal.h"
     nor "libnm-core/nm-utils-private.h" so the static library is usable
     by nmcli which couldn't access these.

Note that "shared/nm-meta-setting.c" is an entirely different case,
because it behaves differently depending on whether linking against
"libnm-core" or the client programs. As such, this file must be compiled
twice.

(cherry picked from commit af07ed01c0)
2019-04-18 20:07:44 +02:00
Thomas Haller
617bdbd8c2 all/trivial: rename NM_UTILS_LOOKUP_STR() to have "_A" suffix
NM_UTILS_LOOKUP_STR() uses alloca(). Partly to avoid the overhead of
malloc(), but more important because it's convenient to use. It does
not require to declare a varible to manage the lifetime of the heap
allocation.

It's quite safe, because the stack allocation is of a fixed size of only
a few bytes. Overall, I think the convenience that we get (resulting in
simpler code) outweighs the danger of stack allocation in this case. It's
still worth it.
However, as it uses alloca(), it still must not be used inside a (unbound)
loop and it is obviously a macro.

Rename the macros to have a _A() suffix. This should make the
peculiarities more apparent.
2019-01-15 09:52:01 +01:00
Thomas Haller
b635b4d419 core: improve and fix keeping connection active based on "connection.permissions"
By setting "connection.permissions", a profile is restricted to a
particular user.
That means for example, that another user cannot see, modify, delete,
activate or deactivate the profile. It also means, that the profile
will only autoconnect when the user is logged in (has a session).

Note that root is always able to activate the profile. Likewise, the
user is also allowed to manually activate the own profile, even if no
session currently exists (which can easily happen with `sudo`).

When the user logs out (the session goes away), we want do disconnect
the profile, however there are conflicting goals here:

1) if the profile was activate by root user, then logging out the user
   should not disconnect the profile. The patch fixes that by not
   binding the activation to the connection, if the activation is done
   by the root user.

2) if the profile was activated by the owner when it had no session,
   then it should stay alive until the user logs in (once) and logs
   out again. This is already handled by the previous commit.

   Yes, this point is odd. If you first do

      $ sudo -u $OTHER_USER nmcli connection up $PROFILE

   the profile activates despite not having a session. If you then

      $ ssh guest@localhost nmcli device

   you'll still see the profile active. However, the moment the SSH session
   ends, a session closes and the profile disconnects. It's unclear, how to
   solve that any better. I think, a user who cares about this, should not
   activate the profile without having a session in the first place.

There are quite some special cases, in particular with internal
activations. In those cases we need to decide whether to bind the
activation to the profile's visibility.

Also, expose the "bind" setting in the D-Bus API. Note, that in the future
this flag may be modified via D-Bus API. Like we may also add related API
that allows to tweak the lifetime of the activation.

Also, I think we broke handling of connection visiblity with 37e8c53eee
"core: Introduce helper class to track connection keep alive". This
should be fixed now too, with improved behavior.

Fixes: 37e8c53eee

https://bugzilla.redhat.com/show_bug.cgi?id=1530977
2018-12-09 14:47:32 +01:00
Thomas Haller
a4bdb161eb device: arm keep-alive instance when queuing active-connection for activation
Now that the keep-alive instance defaults to ALIVE by default, we can
always arm it when starting to activate the active-connection.

The keep-alive instance may have been armed earlier already:
for example, when binding its lifetime to a D-Bus name or
when watching the connection's visible state.

However, at the moment when we queue the active-connection for
activation, we also want to make sure that the keep-alive instance is
armed. It is nicer for consistancy reasons.

Note, that nm_keep_alive_arm() has no effect if nm_keep_alive_disarm()
was called earlier already. Also note, that NMActiveConnection will
disarm the keep-alive instance, when changing to a state greater than
ACTIVATED. So, all works together nicely.

Also, no longer arm the keep-alive instance in the constructor of
NMActiveConnection. It would essentially mean, that the instances
is aremd very early.

Also, as alternative point of interest, arm the keep-alive instance
when registering the signal handler in "nm-policy.c".
2018-12-09 14:47:32 +01:00
Thomas Haller
f95a526366 keep-alive: use NMKeepAlive API directly instead of via NMActiveConnection
NMKeepAlive is a proper GObject type, with a specific API that on the one
end allows to configure watches/bindings, and on the other end exposes
and is-alive property and the owner instance. That's great, as NMActiveConnection
is not concerned with either end (moving complexity away from
"nm-active-connection.c") and as we later can reuse NMKeepAlive with
NMSettingsConnection.

However, we don't need to wrap this API by NMActiveConnection. Doing so
means, we need to expose all the watch/bind functions also as part of
NMActiveConnection API.

The only ugliness here is, that NMPolicy subscribes to property changed
signal of the keep alive instance, which would fail horribly if
NMActiveConnection ever decides to swap the keep alive instance (in
which case NMPolicy would have to disconnect the signal, and possibly
reconnect it to another NMKeepAlive instance). We avoid that by just not
doing that and documenting it.
2018-12-09 14:47:31 +01:00
Thomas Haller
9e8c3d2ebf keep-alive: let NMKeepAlive instance access the owner object that it is keeping alive
NMKeepAlive is a full API independent of NMActiveConnection. For good
reasons:

  - it moves complexity away from nm-active-connection.c

  - in the future, we can use NMKeepAlive also for NMSettingsConnection

As such, the user should also directly interact with NMKeepAlive,
instead of going through NMActiveConnection. For that to work, it
must be possible to get the owner of the NMKeepAlive instance,
which is kept alive.
2018-12-09 14:47:31 +01:00
Thomas Haller
7578e59ba9 keep-alive: rename nm_keep_alive_sink() to nm_keep_alive_arm()
The names "floating" and "sink()" are well known and good.

However, "disarm()" seems the best name for the counterpart operation,
better than "float()", "unsink()", or "freeze()".

Since we have "nm_keep_alive_disarm()", for consitency rename

  - "floating" -> (not) "armed"
  - "sink()"   -> "arm()"
2018-12-09 14:47:31 +01:00
Thomas Haller
a1e811b427 keep-alive: drop "floating" argument from nm_keep_alive_new()
All callers only want to create floating instances at first.
Also, it seems to make generally more sense this way: you create
a floating instance, set it up, and then arm it.

This simplifies nm_keep_alive_new(), which previously was adding
additional code that wasn't accessible via plain g_object_new().
2018-12-09 14:47:31 +01:00
Thomas Haller
15033be1a3 keep-alive: add nm_keep_alive_disarm() to silence notifications once we disconnect
The NMKeepAlive instance is useful to find out when we should disconnect.
The moment when we start disconnecting, we don't care about it anymore.

Add a nm_keep_alive_disarm() function to suppress property change events about
the alive state, after that point. Emitting further events from that point
on is only confusing.

Yes, this means, a NMKeepAlive instance shall not be re-used for
multiple purposes. Create a separate keep-alive instace for each target
that should be guarded.

Also, once disarmed, we can release all resources that the NMKeepAlive instance
was holding until now.
2018-12-09 14:47:31 +01:00
Thomas Haller
58923de4e4 keep-alive: various style fixes
Some trivial changes:

- move nm_keep_alive_new() after nm_keep_alive_init(), so that the
  functions that initialize the instance are beside each other.
- prefer nm_streq*() over strcmp().
- wrap some lines.
- remove some empty lines.
2018-11-17 12:50:58 +01:00
Thomas Haller
7842a58055 keep-alive: drop unused error argument 2018-11-17 12:43:25 +01:00
Benjamin Berg
eb883e34a5 core: Add option to AddAndActivateConnection2 to bind the lifetime
This allows binding the lifetime of the created connection to the
existance of the requesting dbus client. This feature is useful if one
has a service specific connection (e.g. P2P wireless) which will not be
useful without the specific service.

This is simply a mechanism to ensure proper connection cleanup if the
requesting service has a failure.
2018-11-17 12:15:40 +01:00
Benjamin Berg
37e8c53eee core: Introduce helper class to track connection keep alive
For P2P connections it makes sense to bind the connection to the status
of the operation that is being done. One example is that a wifi display
(miracast) P2P connection should be shut down when streaming fails for
some reason.

This new helper class allows binding a connection to the presence of a
DBus path meaning that it will be torn down if the process disappears.
2018-11-17 12:15:40 +01:00
Thomas Haller
38273a8871 settings: use delegation instead of inheritance for NMSettingsConnection and NMConnection
NMConnection is an interface, which is implemented by the types
NMSimpleConnection (libnm-core), NMSettingsConnection (src) and
NMRemoteConnection (libnm).

NMSettingsConnection does a lot of things already:

  1) it "is-a" NMDBusObject and exports the API of a connection profile
     on D-Bus
  2) it interacts with NMSettings and contains functionality
     for tracking the profiles.
  3) it is the base-class of types like NMSKeyfileConnection and
     NMIfcfgConnection. These handle how the profile is persisted
     on disk.
  4) it implements NMConnection interface, to itself track the
     settings of the profile.

3) and 4) would be better implemented via delegation than inheritance.

Address 4) and don't let NMSettingsConnection implemente the NMConnection
interface. Instead, a settings-connection references now a NMSimpleConnection
instance, to which it delegates for keeping the actual profiles.

Advantages:

  - by delegating, there is a clearer separation of what
    NMSettingsConnection does. For example, in C we often required
    casts from NMSettingsConnection to NMConnection. NMConnection
    is a very trivial object with very little logic. When we have
    a NMConnection instance at hand, it's good to know that it is
    *only* that simple instead of also being an entire
    NMSettingsConnection instance.

    The main purpose of this patch is to simplify the code by separating
    the NMConnection from the NMSettingsConnection. We should generally
    be aware whether we handle a NMSettingsConnection or a trivial
    NMConnection instance. Now, because NMSettingsConnection no longer
    "is-a" NMConnection, this distinction is apparent.

  - NMConnection is implemented as an interface and we create
    NMSimpleConnection instances whenever we need a real instance.
    In GLib, interfaces have a performance overhead, that we needlessly
    pay all the time. With this change, we no longer require
    NMConnection to be an interface. Thus, in the future we could compile
    a version of libnm-core for the daemon, where NMConnection is not an
    interface but a GObject implementation akin to NMSimpleConnection.

  - In the previous implementation, we cannot treat NMConnection immutable
    and copy-on-write.
    For example, when NMDevice needs a snapshot of the activated
    profile as applied-connection, all it can do is clone the entire
    NMSettingsConnection as a NMSimpleConnection.
    Likewise, when we get a NMConnection instance and want to keep
    a reference to it, we cannot do that, because we never know
    who also references and modifies the instance.
    By separating NMSettingsConnection we could in the future have
    NMConnection immutable and copy-on-write, to avoid all unnecessary
    clones.
2018-08-28 22:27:55 +02:00
Lubomir Rintel
6c2eb953d5 active-connection: fix build with clang-6.0
glib 2.56's g_steal_pointer() won't tolerate a function pointer in place
of a gpointer.

  CC       src/src_libNetworkManager_la-nm-active-connection.lo
    src/nm-active-connection.c:1017:17: error: pointer type mismatch
      ('NMActiveConnectionAuthResultFunc' (aka 'void (*)(struct _NMActiveConnection *,
      int, const char *, void *)') and 'gpointer' (aka 'void *'))
      [-Werror,-Wpointer-type-mismatch]
                result_func = g_steal_pointer (&priv->auth.result_func);
                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  /usr/include/glib-2.0/glib/gmem.h:200:6: note: expanded from macro 'g_steal_pointer'
    (0 ? (*(pp)) : (g_steal_pointer) (pp))
       ^ ~~~~~~~   ~~~~~~~~~~~~~~~~~~~~~~
  1 error generated.

There's just a single spot we use it that way, so it's perhaps better to
work around the warning instead of disabling it.
2018-05-21 12:02:26 +02:00
Francesco Giudici
5e8c12eece active-connection: fix harmless typo 2018-05-18 10:22:32 +02:00
Thomas Haller
5a1f84b085 core: add activation-reasons for external/assume connections
Until now, we only really cared about whether a connection was activated
with reason NM_ACTIVATION_REASON_AUTOCONNECT_SLAVES or not.

Now however, we will care about whether a connection was activated via
(genuine) autoconnect by NMPolicy, or external/assume by NMManager.
Add a new reason to distinguish between them.
2018-04-30 16:36:29 +02:00
Thomas Haller
dc2004ddfb core: fix cancelling of authorization request for active connection
The async authorization request also carries user-data and its result
must always be handled. For example, it might carry a GDBusMethodInvocation
context, which must be returned and freed.

Hence, when cancelling the request, we must always invoke the callback.

Also, when the NMActiveConnection progresses to state disconnected,
automatically abort the authorization request.
2018-04-24 10:23:14 +02:00
Thomas Haller
9a579171b5 core: fix unreachable assertion in nm_active_connection_set_state() 2018-04-24 09:03:39 +02:00
Thomas Haller
9abe3dc1a4 core: rework passing user-data to nm_active_connection_authorize()
Previously, nm_active_connection_authorize() accepts two user-data
pointers for convenience.

nm_active_connection_authorize() has three callers. One only requires
one user-data, one passes two user-data pointers, and one requires
three pointer.

Also, the way how the third passes the user data (via
g_object_set_qdata_full()) is not great.

Let's only use one user-data pointer. We commonly do that, and it's easy
enough to allocate a buffer to pack multiple pointers together.
2018-04-24 09:03:39 +02:00
Thomas Haller
580a11da3a core: minor cleanup of handling specific-object in NMActiveConnection
- use nm_assert() for something that ~really~ always should be given.
- use nm_streq0() and nm_clear_g_free().
2018-04-18 07:55:15 +02:00
Thomas Haller
476208d223 core: don't explicitly set D-Bus path properties to "/"
NMDBusObject already gets this right, by calling nm_dbus_utils_get_property(),
which calls g_dbus_gvalue_to_gvariant(), which correctly converts NULL
object paths to "/".

We already rely on that elsewhere. No need for this workaround.
2018-04-18 07:55:15 +02:00
Thomas Haller
5284690f18 core: use nm_utils_dbus_normalize_object_path() to cleanup D-Bus argument 2018-04-18 07:55:15 +02:00
Thomas Haller
8df245d773 settings: make NM_SETTINGS_CONNECTION_FLAGS property NM_SETTINGS_CONNECTION_FLAGS_CHANGED signal
For one, these flags are "internal" flags. Soon, we will gain
a new NMSettingsConnectionFlags type that is exported on D-Bus
and partly overlaps with these internal flags. However, then we
will need the "flags" properties to expose the public bits.

This property only exists because other parts are interested in
notification signals. Note that we encourage NMDbusObject types
to freeze/thaw property-changed notifications. As freezing the
notifications also delays the signals, this is not desired for
the purpose where internal users subscribe to the signal.
2018-04-16 15:30:07 +02:00
Thomas Haller
417c7ebe4a core/trivial: rename "NMSettingsConnectionFlags" to "NMSettingsConnectionIntFlags"
"NMSettingsConnectionFlags" was an internal enum. Soon, we will add such
a type in libnm. Avoid the naming conflict by renaming. The "Int" stands
for "internal".
2018-04-16 15:30:07 +02:00
Thomas Haller
c05088a09b core: don't use NMAuthChain in NMActiveConnection but directly schedule events
More of a proof of concept, how convenient (or not) it is to drop
NMAuthChain and use NMAuthManager's API directly. I think it's
reasonably nice.

As before, when asking for both general network-control permissions
and wifi-shared-permissions, we will not fail with
wifi-shared-permissions, as long as network-control check is still
pending. The effect is, that the error response preferably complains
about no permissions to network-control (in case both permissions
are missing).

One change in behavior is, if network-control authorization check
fails before wifi-shared-permissions, we declare the result and
cancel the pending wifi-shared-permissions. Previously, we would
have waited for both results. The change in behavior is not merely
that we declare the result earlier, but also that NMAuthManager will
actively send a "CancelCheckAuthorization" D-Bus call to cancel the
still pending wifi-shared-permissions check.
2018-04-13 09:09:46 +02:00
Thomas Haller
50b74731f6 auth-chain/trivial: rename nm_auth_chain_unref() to nm_auth_chain_destroy()
NMAuthChain is not really ref-counted. True, we have an internal ref-counter
to ensure that the instance stays alive while the callback is invoked. However,
the user cannot take additional references as there is no nm_auth_chain_ref().

When the user wants to get rid of the auth-chain, with the current API it
is important that the callback won't be called after that point. From the
name nm_auth_chain_unref(), it sounds like that there could be multiple references
to the auth-chain, and merely unreferencing the object might not guarantee that
the callback is canceled. However, that is luckily not the case, because
there is no real ref-counting involved here.

Just rename the destroy function to make this clearer.
2018-04-13 09:09:46 +02:00
Thomas Haller
1acb3622aa core: use NMDBusTrackObjPath for NM_ACTIVE_CONNECTION_CONNECTION path 2018-04-13 09:09:46 +02:00
Thomas Haller
0dd3e6099c core: don't unexport active-connection when settings connection disappears
When a settings-connection gets deleted, we need to bring down the
NMActiveConnection that contains it. However, we shouldn't just unexport
the active connection from D-Bus. Instead, clear the settings path.

We need to drop the path, because the connection is going away. It's a
bit ugly, that an active-connection might reference no
settings-connection. However, this only happens during shut-down.
The alternative, would be to keep the settings-connection object
in a zombie state, exported on D-Bus. However, that seems even more
confusing to me.
2018-04-13 09:09:46 +02:00
Thomas Haller
9efa7c7220 core: use nm_dbus_object_get_path() instead of nm_connection_get_path()
Essentially, nm_connection_get_path() mirros nm_dbus_object_get_path().
However, when cloning a simple-connection, the path also gets cloned.

I think this field doesn't belong to NMConnection in the first place,
because NMConnection is not a D-Bus object. NMSettingsConnection (in
core) and NMRemoteConnection (in libnm) is.

Don't use the misleading alias, but use nm_dbus_object_get_path()
directly.
2018-04-13 09:09:46 +02:00
Thomas Haller
efe5cf79c0 core: simplify NMActiveConnection.get_property to not create temporary GPtrArrray
Fixes: c050fb7cd2
2018-04-13 09:09:46 +02:00
Thomas Haller
67e06924e1 core/trivial: add code comment to NMActiveConnection's get_property() 2018-04-13 09:09:46 +02:00
Beniamino Galvani
43a0f47ea2 core: specify an activation reason for active connections
Specify a reason when creating active connections. The reason will be
used in the next commit to tell whether slaves must be reconnected or
not if a master has autoconnect-slaves=yes.
2018-04-08 09:40:14 +02:00
Thomas Haller
57ab9fd60f core/dbus: rework creating numbered D-Bus export path by putting counter into class
I dislike the static hash table to cache the integer counter for
numbered paths. Let's instead cache the counter at the class instance
itself -- since the class contains the information how the export
path should be exported.

However, we cannot use a plain integer field inside the class structure,
because the class is copied between derived classes. For example,
NMDeviceEthernet and NMDeviceBridge both get a copy of the NMDeviceClass
instance. Hence, the class doesn't contain the counter directly, but
a pointer to one counter that can be shared between sibling classes.
2018-03-13 11:29:18 +01:00
Thomas Haller
297d4985ab core/dbus: rework D-Bus implementation to use lower layer GDBusConnection API
Previously, we used the generated GDBusInterfaceSkeleton types and glued
them via the NMExportedObject base class to our NM types. We also used
GDBusObjectManagerServer.

Don't do that anymore. The resulting code was more complicated despite (or
because?) using generated classes. It was hard to understand, complex, had
ordering-issues, and had a runtime and memory overhead.

This patch refactors this entirely and uses the lower layer API GDBusConnection
directly. It replaces the generated code, GDBusInterfaceSkeleton, and
GDBusObjectManagerServer. All this is now done by NMDbusObject and NMDBusManager
and static descriptor instances of type GDBusInterfaceInfo.

This adds a net plus of more then 1300 lines of hand written code. I claim
that this implementation is easier to understand. Note that previously we
also required extensive and complex glue code to bind our objects to the
generated skeleton objects. Instead, now glue our objects directly to
GDBusConnection. The result is more immediate and gets rid of layers of
code in between.
Now that the D-Bus glue us more under our control, we can address issus and
bottlenecks better, instead of adding code to bend the generated skeletons
to our needs.

Note that the current implementation now only supports one D-Bus connection.
That was effectively the case already, although there were places (and still are)
where the code pretends it could also support connections from a private socket.
We dropped private socket support mainly because it was unused, untested and
buggy, but also because GDBusObjectManagerServer could not export the same
objects on multiple connections. Now, it would be rather straight forward to
fix that and re-introduce ObjectManager on each private connection. But this
commit doesn't do that yet, and the new code intentionally supports only one
D-Bus connection.
Also, the D-Bus startup was simplified. There is no retry, either nm_dbus_manager_start()
succeeds, or it detects the initrd case. In the initrd case, bus manager never tries to
connect to D-Bus. Since the initrd scenario is not yet used/tested, this is good enough
for the moment. It could be easily extended later, for example with polling whether the
system bus appears (like was done previously). Also, restart of D-Bus daemon isn't
supported either -- just like before.

Note how NMDBusManager now implements the ObjectManager D-Bus interface
directly.

Also, this fixes race issues in the server, by no longer delaying
PropertiesChanged signals. NMExportedObject would collect changed
properties and send the signal out in idle_emit_properties_changed()
on idle. This messes up the ordering of change events w.r.t. other
signals and events on the bus. Note that not only NMExportedObject
messed up the ordering. Also the generated code would hook into
notify() and process change events in and idle handle, exhibiting the
same ordering issue too.
No longer do that. PropertiesChanged signals will be sent right away
by hooking into dispatch_properties_changed(). This means, changing
a property in quick succession will no longer be combined and is
guaranteed to emit signals for each individual state. Quite possibly
we emit now more PropertiesChanged signals then before.
However, we are now able to group a set of changes by using standard
g_object_freeze_notify()/g_object_thaw_notify(). We probably should
make more use of that.

Also, now that our signals are all handled in the right order, we
might find places where we still emit them in the wrong order. But that
is then due to the order in which our GObjects emit signals, not due
to an ill behavior of the D-Bus glue. Possibly we need to identify
such ordering issues and fix them.

Numbers (for contrib/rpm --without debug on x86_64):

- the patch changes the code size of NetworkManager by
  - 2809360 bytes
  + 2537528 bytes (-9.7%)

- Runtime measurements are harder because there is a large variance
  during testing. In other words, the numbers are not reproducible.
  Currently, the implementation performs no caching of GVariants at all,
  but it would be rather simple to add it, if that turns out to be
  useful.
  Anyway, without strong claim, it seems that the new form tends to
  perform slightly better. That would be no surprise.

  $ time (for i in {1..1000}; do nmcli >/dev/null || break; echo -n .;  done)
  - real    1m39.355s
  + real    1m37.432s

  $ time (for i in {1..2000}; do busctl call org.freedesktop.NetworkManager /org/freedesktop org.freedesktop.DBus.ObjectManager GetManagedObjects > /dev/null || break; echo -n .; done)
  - real    0m26.843s
  + real    0m25.281s

- Regarding RSS size, just looking at the processes in similar
  conditions, doesn't give a large difference. On my system they
  consume about 19MB RSS. It seems that the new version has a
  slightly smaller RSS size.
  - 19356 RSS
  + 18660 RSS
2018-03-12 18:37:08 +01:00