nm_settings_get_connections() returns a sorted list. We have many users
of nm_connection_provider_get_connection(), which returns the same result,
but undefined order.
Next NMConnectionProvider will be dropped. Thus, we don't want to
seamlessly replace nm_connection_provider_get_connection() by a sorted
version nm_settings_get_connections().
Rename nm_settings_get_connections() to make clear it is sorted.
For a type to be inheritable, its public struct (NMManager) must
be known. As nobody inherits NMManager, we can make it private.
As the struct is private anyway, we can also reuse it for the private
data directly, instead of registering NMManagerPrivate in the manager
class.
There are advantages and disadvantages:
+ simplifies debugging, as the self pointer also contains the
private data.
+ removes a small overhead of tracking the private data separately
- is a different way to implement the class, contrary to many
other classes.
- inheriting from the class later requires reverting this change
(but we will never inherit from NMManager).
- as it is now, nobody uses the priv field directly and we still
access it via NM_MANAGER_GET_PRIVATE(self). However, the presence
of the priv field might encourage us to use it directly -- which
increases above disadvantages.
The only user of the sleep-monitor singleton was NMManager anyway.
Also, even if we ever get more users that are interested in the SLEEPING
signal, we would hook them onto NMManager -- because NMManager should
collect, coordinate and possibly forward the SLEEPING signal. In no case,
another object should react on the SLEEPING signal and thus bypassing the
NMManager.
The main purpose of audit logging is to understand who did what to the
system configuration, so it is useful to log also the list of changed
properties when a connection is updated:
op="connection-update"
uuid="2f3e48fc-5f47-41d9-9278-d2871378df43"
name="pppoe1"
args="pppoe.username,pppoe.password" <========
pid=9523
uid=1001
result="success"
This is mostly interesting of NMPolicy, which no longer needs to
subscribe to two almost identical signals (where the by-user signal
was always invoked together with the plain "updated" signal).
After all, this state is stored persistently to /var/lib/NetworkManager,
and not to volatile storage in /var/run. Hence the name is better.
It's also shorter, so rename it.
The commit is mostly trivial, including update of code comments
and logging messages.
Fixes: 1b43c880ba
Move reading and writing of the state file to NMConfig
("/var/lib/NetworkManager/NetworkManager.state" file).
Originally, I intended to persist more state, thus it made
sense to cleanup handling of the state file and move it all
at one place. Now, it's not clear that will happen anytime soon.
Still, the change is a worthy cleanup, so do it anyway.
https://bugzilla.gnome.org/show_bug.cgi?id=764474
If the manager removes the device, the IP config objects must
be cleared. The reason is that NMPolicy registers to the IP config
changed signal and passes these object on to NMDnsManager.
If the INTERNAL_DEVICE_REMOVED signal is emited with IP configuration
object pending, those objects will be leaked.
This partly redoes commit f72816bf10,
which was reverted.
Co-Authored-By: Thomas Haller <thaller@redhat.com>
https://bugzilla.gnome.org/show_bug.cgi?id=764483
First let the device know it's being removed soon so that it has a
chance to clean up the IP configuration early.
If the manager removes the device fist, the policy never learns of
config removal and doesn't unhook it from the DNS manager resulting in a
IPConfig leak and possible wrong DNS configuration in effect.
Also adjust the route manager to skip over devices without IP
configuration when determining the best connection; it is perhaps
just due to being removed.
https://bugzilla.gnome.org/show_bug.cgi?id=764483
This makes sure that devices like bond get their dhcp renewed
[thaller@redhat.com: original patch modified to rename
now-public function update_dynamic_ip_setup()]
https://bugzilla.gnome.org/show_bug.cgi?id=764398
Make sure there's always the device and connection as well as the reason
when a slave activation fails. The slave connection could in fact be
chosen automatically on "nmcli d connect" and the user might not be
aware activation of which connection was attempted:
$ nmcli d connect enp0s25
Error: Device activation failed: Master connection not found or invalid
When porting to GDBus property change notifications were converted from a
hash table to a GVariantBuilder. GVariantBuilder doesn't care about
duplicated properties in the dict so each g_object_notify() will add
an additional item with possibly different values:
signal time=1458571005.592811 sender=:1.10 -> destination=(null destination) serial=64451 path=/org/freedesktop/NetworkManager; interface=org.freedesktop.NetworkManager; member=PropertiesChanged
array [
dict entry(
string "ActiveConnections"
variant array [
object path "/org/freedesktop/NetworkManager/ActiveConnection/19"
object path "/org/freedesktop/NetworkManager/ActiveConnection/18"
object path "/org/freedesktop/NetworkManager/ActiveConnection/15"
object path "/org/freedesktop/NetworkManager/ActiveConnection/0"
]
)
dict entry(
string "ActiveConnections"
variant array [
object path "/org/freedesktop/NetworkManager/ActiveConnection/24"
object path "/org/freedesktop/NetworkManager/ActiveConnection/19"
object path "/org/freedesktop/NetworkManager/ActiveConnection/18"
object path "/org/freedesktop/NetworkManager/ActiveConnection/15"
object path "/org/freedesktop/NetworkManager/ActiveConnection/0"
]
)
]
Fix that by not emitting notify events for the manager's ActiveConnections
property until the property has actually been updated in active_connection_add().
The unexport also isn't required for VPN connections since it will get
unexported when it's disposed after _internal_activation_failed() gets called.
This can regularly happen when a virtual device depends on a parent/master
that is not yet created. We will retry later when the parent is ready, so
logging a warning about it is wrong and confusing.
AddAndActivateConnection is allowed to provide an incomplete connection
that will be completed by NetworkManager. That is, a connection that
does not verify.
But we still want to catch invalid properties or unknown setting types.
Thus, we want to reject invalid partial connections.
This possibly rejects invalid requests from clients that were accepted
before. Thus this change has the potential to break misbehaving clients.
Don't try to realize our device when the parent device is not real.
Instead, enqueue the activation and wait until it is active before
realizing our device and progressing the device to DISCONNECTED so that
it can get connected.
We'll need to share the best conneciton logic and it's the only caller
of nm_device_get_available_connections(). Let's just move it all to
NMDevice and provide the best connection from there instead.
During startup, when a link is detected (enp0s25 in the example below)
we try to create also virtual devices (ipip1) on it through
system_create_virtual_device(), however this realizes only devices for
connections which can autoactivate.
To support the assumption of child devices with autoconnect=no, we
should take in consideration in retry_connections_for_parent_device()
only connections for which the link does not exist, and let existing
links be handled by platform_link_added(), which also realizes them.
Reproducer:
$ nmcli c add type ip-tunnel ifname ipip1 con-name ipip1+ autoconnect no \
mode ipip remote 172.25.16.1 dev enp0s25 ip4 1.2.3.4/31
$ nmcli c up ipip1+
$ systemctl restart NetworkManager
Result:
* before: ipip1+ is not assumed, ipip1 is not present in 'nmcli d' output
* after: ipip1+ is assumed, ipip1 detected
str_if_set() was added to replace the non-standard gcc extension "?:".
However, "?:" is supported by clang as well and we already use it at
several places.
Also, str_if_set() did not follow our naming scheme and renaming to
nm_str_if_set() would be ugly. So just drop it.
GError codes are only unique per domain, so logging the code without
also indicating the domain is not helpful. And anyway, if the error
messages are not distinctive enough to tell the whole story then we
should fix the error messages.
Based-on-patch-by: Dan Winship <danw@gnome.org>
Functions that take a GError** MUST fill it in on error. There is no
need to check whether error is NULL if the function it was passed to
had a failing return value.
Likewise, a proper GError must have a non-NULL message, so there's no
need to double-check that either.
Based-on-patch-by: Dan Winship <danw@gnome.org>
- All internal source files (except "examples", which are not internal)
should include "config.h" first. As also all internal source
files should include "nm-default.h", let "config.h" be included
by "nm-default.h" and include "nm-default.h" as first in every
source file.
We already wanted to include "nm-default.h" before other headers
because it might contains some fixes (like "nm-glib.h" compatibility)
that is required first.
- After including "nm-default.h", we optinally allow for including the
corresponding header file for the source file at hand. The idea
is to ensure that each header file is self contained.
- Don't include "config.h" or "nm-default.h" in any header file
(except "nm-sd-adapt.h"). Public headers anyway must not include
these headers, and internal headers are never included after
"nm-default.h", as of the first previous point.
- Include all internal headers with quotes instead of angle brackets.
In practice it doesn't matter, because in our public headers we must
include other headers with angle brackets. As we use our public
headers also to compile our interal source files, effectively the
result must be the same. Still do it for consistency.
- Except for <config.h> itself. Include it with angle brackets as suggested by
https://www.gnu.org/software/autoconf/manual/autoconf.html#Configuration-Headers
Since the device-for-all merge it's a sin (trips an assert) to create an
activation request with NULL device.
If we get here, it's probably that the master device exists, but is not ready
for activation (it's in UNMANAGED state in the process of being created).
We not only want to check the device name when creating a virtual device, but
also when determining if the connection can actually be activated there.
Otherwise the device names will mix up if there's more connections that use
virtual devices of the same type.