A lot of drivers actually support changing the MAC address of a link
without taking it down.
Taking down a link is very bad, because kernel will remove routes
and IPv6 addresses.
For example, if the user used a dispatcher script to add routes,
these will be lost. Note that we may change the MAC address of a
device any time. For example, a VLAN device watches the parent's
MAC address and configures it (with a logging message "parent hardware
address changed to ...").
Try first whether we can change the MAC address without taking the
link down. Only if that fails, retry with taking it down first.
https://bugzilla.redhat.com/show_bug.cgi?id=1639274
Add helper nm_platform_link_get_ifi_flags() to access the
ifi-flags.
This replaces the internal API _link_get_flags() and makes it public.
However, the return value also allows to distinguish between errors
and valid flags.
Also, consider non-visible links. These are links that are in netlink,
but not visible in udev. The ifi-flags are inherrently netlink specific,
so it seems wrong to pretend that the link doesn't exist.
Working on NetworkManager 1.12.4 and sometimes (rarely), when creating
a NM client object before NetworkManager service start, this object will
never be running.
In that case, we can see the following log:
"[GLIB-GLib-GIO WARN] Error calling GetManagedObjects() when name
owner :1.5 for name org.freedesktop.NetworkManager came back:
GDBus.Error:org.freedesktop.DBus.Error.UnknownMethod:
No such interface 'org.freedesktop.DBus.ObjectManager' on object
at path /org/freedesktop".
Object Manager object shall be registered before requesting dbus name
to be sure that 'org.freedesktop.Dbus.ObjectManager' interface is present
when name owner change is received by libnm.
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/51
dhcp_identifier_set_iaid() is no longer called. Replace
the code with an assertion and always fail.
The function was already annoying previously, because it would
require udev API to generate the IAID. So, we were already required
to patch this function.
During start, sd_dhcp6_client would call client_ensure_iaid(),
to initialize the IAID.
First of all, the IAID is important to us, we should not leave the
used IAID up to an implementation detail. In the future, we possibly
want to make this configurable.
The problem is that client_ensure_iaid() calls dhcp_identifier_set_iaid()
which looks up the interface name via if_indextoname() (in our fork).
The problem is that dhcp_identifier_set_iaid() looks up information by
quering the system, which makes it hard for testing and also makes it
unpredictable. It's better to use our implementation nm_utils_create_dhcp_iaid(),
which is solely based on the interface-name, which is given as a well
defined parameter to the DHCP client instance.
config_parse_iaid(), dhcp_identifier_set_iaid() and sd_dhcp6_client_set_iaid() all
allow for the IAID to be zero. Also, RFC 3315 makes no mention that zero
would be invalid.
However, client_ensure_iaid() would take an IAID of zero as a sign that
the values was unset. Fix that by keeping track whether IAID is
initialized.
https://github.com/systemd/systemd/pull/108950e408b82b8
nm_utils_get_monotonic_timestamp*() inherrently use static data. Let's
initialize it in a thread safe manner.
nm_utils_get_monotonic_timestamp*() are a fundamental utility function
that should work correctly in all cases. Such a low level function should
be thread safe.
Sometimes the test fail:
$ make -j 10 src/platform/tests/test-address-linux
$ while true; do
NMTST_DEBUG=d ./tools/run-nm-test.sh src/platform/tests/test-address-linux 2>&1 > log.txt || break;
done
fails with:
ERROR: src/platform/tests/test-address-linux - Bail out! test:ERROR:src/platform/tests/test-common.c:790:nmtstp_ip_address_assert_lifetime: assertion failed (adr <= lft): (1001 <= 1000)
That is, because of a wrong check. Fix it.
g_object_set_property() cannot fail nor signal an error reason when
invalid arguments are passed. Use our wrapper nm_g_object_set_property()
instead.
Note that the input argument comes from untrusted (although authenticated)
source.
In general we want to keep the connections that the user is most likely
to want to see topmost. Default connections should be close to the top,
but the connections that are likely to have been brought up manually
shall be above them. It applies to VPN connections and should apply to
Hotspots too.
In editor_menu_main(), after saving a connection we wait that the
Update2() D-Bus call returns and then we copy the NMRemoteConnection
instance over to @connection.
This assumes that when Update2() returns the remote connection
instance is already updated with new settings. Indeed, on server side
the NMSettingsConnection first emits the "Updated" signal and then
returns to Update2(). However, the Updated signal doesn't include the
new setting values and so libnm has to fire an asynchronous
nmdbus_settings_connection_call_get_setting() to fetch the new
settings, which terminates after the Update2().
So, to be sure that the remote connection got updated we have also to
listen to the connection-changed signal, which is always emitted after
an update.
https://bugzilla.redhat.com/show_bug.cgi?id=1546805
Connection secrets are lost after calling
nm_connection_replace_settings_from_connection() because @con_tmp
doesn't contain secrets; refetch them like we do when starting the
editor.
CAK is a connection secret and can be NULL for various reasons
(agent-owned, no permissions to get secrets, etc.). verify() must not
require it.
Fixes: 474a0dbfbe
Upside:
- it may avoid a D-Bus call altogether.
- currently there is no API to bind/unbind an existing NMActiveConnection,
it can only be bound initially with AddAndActivate2.
That makes sense when the calling applicatiion only wants to keep the
profile active for as long as it lives. It never intends to extend the
lifetime beyond that. In such a case, it is expected that eventually
we need to be sure whether the D-Bus client is still alive, as we
make a decision based on that. In that case, we eventually will call
GetNameOwner and nothing is saved.
A future feature could add D-Bus API to bind/unbind existing active
connections after creation. That would allow an application to
activate profiles and -- if anything goes wrong -- to be sure
that the profile gets deactivted. Only in the success case, it
would unbind the lifetime in a last step and terminate. Un such
a case, binding to a D-Bus client is more of a fail-safe mechanism
and commonly not expected to come into action.
This is an interesting feature, because ActivateConnection D-Bus call
may take a long time, while perfroming interactive polkit authentication.
That means, `nmcli connection up $PROFILE` can fail with timeout before
the active connection path is even created, but afterwards the profile may
still succeed to activate. That seems wrong. nmcli could avoid that,
by binding the active connection to itself, and when nmcli exits
with failure, it would make sure that the active connection gets
disconnected as well.
Downside:
- the code is slightly more complicated(?).
- if the D-Bus name is indeed gone (but the NMKeepAlive is still alive
for other reasons), we will not unregister the D-Bus signal, because we
never learn that it's gone. It's not a leak, but an unnecessary
signal subscription.
- during nm_keep_alive_set_dbus_client_watch() we don't notice right
away that the D-Bus client is already gone. That is unavoidable as
we confirm the state asynchronously.
If the NMKeepAlive is kept alive for other reasons but only later
depends on presence of the D-Bus client, then in the non-lazy approach
we would have noticed already that the client is gone, and would disconnect
right away. With the lazy approach, this takes another async D-Bus call to
notice.
When we subscribe the signal fo NameOwnerChanged, we are not sure
that the name-owner is currently alive.
Issue a GetNameOwner call to make sure.
Co-authored-by: Thomas Haller <thaller@redhat.com>
Fixes: 37e8c53eee
"bind" specifically binds the lifetime of the activation (NMActiveConnection).
In combination with "persist=volatile", the lifetime of the NMSettingsConnection
is indirectly bound to the NMActiveConnection. But still these concepts make sense
independently.
In the future, it may make sense to also bind the lifetime of the NMSettingsConnection
to the D-Bus client. Hence, rename the option to allow for the distinction.
Also, belatedly fix libnm comment about "bind" only working with
"persist" "volatile".
Fixes: eb883e34a5
Synchronous D-Bus calls seems harmful to me, such API should not be
added to libnm. As such, all API is by default and preferably "_async".
Don't add an "_async" suffix. While we are not consistent in libnm about
this, I think for new code we should.
- use nm_streq() instead of g_strcmp0(). I think streq() is easier
to understand.
- the strings that are checked here must never be %NULL, because they come
from string variants. Use nm_streq() instead of nm_streq0() or g_strcmp0().
- don't add a "." to the GError messages. GError messages are commonly
embedded in a larger message, and shoult not themself contain the dot.
Previously, @bind_lifetime was a string. While parsing the @options, we
would set the string to the content of the parsed GVariant. Note that
the GVariant is unrefed before we access @bind_lifetime, thus it's
not guaranteed that it will still exist.
Arguably, the string GVariant's lifetime is tied to the @options
dictionary, so indeed it lives long enough. But that is not-obviously
the case.
Fix that by using a boolean instead. Also, rename @bind_lifetime to
@bind_dbus_client.
For one, there was a bug here: we cannot "goto error" without setting
the @error variable.
Anyway, restricting "bind" "dbus-client" only to profiles that are
"persist" mode "volatile" seems wrong. The "bind" option as it is,
limits the lifetime of the active-connection. This has no direct relation
with the lifetime of the setting-connection. Indeed, if the
settings-connection's lifetime is itself set to "volatile", then
it will indeed go away with the active-connection. However, these
two concepts are not strictly related.
In the future, we might add an option to limite the lifetime of
a settings-connection to a D-Bus client ("bind-setting"). Possibly
we should thus rename "bind" to "bind-activation", to make the
distinction clearer.
Most (not all) functions that can fail and report the reason with
an GError are required to set the error if they fail. It's a bug
to claim to fail without returning the GError reason.
Hence, our callers usually don't check whether a GError is present but
just access it.
Likewise, for better or worse, our GError codes are often not meaningful
(unless explicitly documented). Meaning, logging the error code number
is not helpful. Instead, error messages should be written in a manner
that one can find the source code location where it happened.
Also, return-early to reduce the indentation level of the code.
Also, drop the code comment. It seems to just describe what is obviously
visible by reading the source. It doesn't explain much beside that the
"doesn't have a reason", but not really why.
- always issue a _notify_alive(), just to be sure. At least
in case where we clear a dbus-client watch, the alive state
could change.
- avoid the logging in cleanup_dbus_watch(), if there is nothing
to cleanup.
- in nm_keep_alive_set_settings_connection_watch_visible(), abort
early when setting the same connection again (or %NULL again).
- nm_keep_alive_set_settings_connection_watch_visible() would (already
before) correctly disconnect the signal handler from the previous
connection.
As we anyway do explict disconnects, avoid the overhead of a weak
pointer with g_signal_connect_object(). Just reuse the same
setter to disconnect the signal in dispose().
- fix leaking priv->connection in nm_keep_alive_set_settings_connection_watch_visible().
- use g_signal_handlers_disconnect_by_func(), to be more specific about
which signal we want to disconnect.
The alive state is composed from various parts, let's only emit
a _notify (self, PROP_ALIVE) when it actually changes.
For that, cache the alive state and let _notify_alive() determine
whether it changed and possibly emit the signal.
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.
This adds the new methods nm_client_add_and_activate_connection_options_*
and ports the existing methods to use the new AddAndActivateConnection2
call rather than AddAndActivateConnection, allowing further parameters
to be passed in.