Since we determine the connectivity state of each device individually,
the global connectivity state is an aggregate of all these states.
I am not sure about considering here devices that don't have the (best)
default route for their respective address family. But anyway.
When we aggregate the best connectivity, we chose the numerical largest
value. That is wrong, because PORTAL is numerically smaller than
LIMITED.
That means, if you have two devices, one with connectivity LIMITED and
one with connectivity PORTAL, then LIMITED wrongly wins.
Fixes: 6b7e9f9b22https://bugzilla.redhat.com/show_bug.cgi?id=1619873
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: 37e8c53eeehttps://bugzilla.redhat.com/show_bug.cgi?id=1530977
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".
Previously, if @active referenced a device but was not currently queued
or the current activation request, nothing was done.
Now, in such a case still call nm_active_connection_set_state_fail().
Note that nm_active_connection_set_state_fail() has no effects on
active-connections that are already in disconnected state (which
we would expect by such an active connection). Likely there is no
visible change here, but it feels more correct to ensure the active
connection is always failed.
nm_device_disconnect_active_connection() is generally useful and a prefered
form to fail an active connection. The device's state-change reason is important,
so it needs to be injected.
Since commit 945c904f95 "platform: assert against valid ifindex and
remove duplicate assertions", it is no longer allowed to call certain
platform functions with invalid ifindex.
These trigger now an assertion. Note that the assertion is merely a
g_return_val_if_fail(), hence in non-debug mode, this does not lead to
a crash.
Fixes: 945c904f95
The problem is that updating the metered value of a shared connection is
not implemented. The user needs to fully reactivate the profile for changes
to take effect.
That is unfortunate, especially because reapplying the route metric
works in other other cases.
Add a new CON_DEFAULT() macro that places a property name into a
special section used at runtime to check whether it is a supported
connection default.
Unfortunately, this mechanism doesn't work for plugins so we have to
enumerate the connection defaults from plugins in the daemon using
another CON_DEFAULT_NOP() macro.
Correct the spelling across the *entire* tree, including translations,
comments, etc. It's easier that way.
Even the places where it's not exposed to the user, such as tests, so
that we learn how is it spelled correctly.
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
nm_device_has_pending_action_reason() marks the device as busy, which in
turn delays "startup-complete" and NetworkManager-wait-online.service.
A device which has no carrier but is otherwise in activated state, is
clearly ready. I didn't test this, but I presume that can easily be the
case with static IP configuration (which can activate without the device
having carrier).
Add a new mode for the DHCPv4 client identifier.
"duid" is what the internal (systemd) DHCP client already does by
default. It is also the same as used by systemd-networkd's
"ClientIdentifier=duid" setting. What we still lack (compared to
networkd) are a way to overwrite IAID and the DUID.
Previously, this mode was used by the internal DHCP plugin
by default. However, it could not be explicitly configured.
In general, our default values should also be explicitly selectable.
Now the "duid" client identifier can also be used with the "dhclient"
plugin.
We already had "${DEVICE}" which uses the interface name.
In times of predictable interface naming, that works well.
It allows the user to generate IDs per device which don't
change when the hardware is replaced.
"${MAC}" is similar, except that is uses the permanent MAC
address of the device. The substitution results in the empty
word, if the device has no permanent MAC address (like software
devices).
The per-device substitutions "${DEVICE}" and "${MAC}" are especially
interesting with "connection.multi-connect=multiple".
- use NMUuid type where appropriate.
- no error handling for generate_duid_from_machine_id().
It cannot fail anymore.
- add thread-safety to generate_duid_from_machine_id() with
double-checked locking.
- use unions for converting the sha256 digest to the target
type.
For testing purpose, it's bad to let nm_utils_stable_id_parse()
directly access nm_utils_get_boot_id_str(). Instead, the function
should have no side-effects.
Since the boot-id is anyway cached, accessing it is cheap. Even
if it likely won't be needed.
Previously, whenever we needed /etc/machine-id we would re-load it
from file. The are 3 downsides of that:
- the smallest downside is the runtime overhead of repeatedly
reading the file and parse it.
- as we read it multiple times, it may change anytime. Most
code in NetworkManager does not expect or handle a change of
the machine-id.
Generally, the admin should make sure that the machine-id is properly
initialized before NetworkManager starts, and not change it. As such,
a change of the machine-id should never happen in practice.
But if it would change, we would get odd behaviors. Note for example
how generate_duid_from_machine_id() already cached the generated DUID
and only read it once.
It's better to pick the machine-id once, and rely to use the same
one for the remainder of the program.
If the admin wants to change the machine-id, NetworkManager must be
restarted as well (in case the admin cares).
Also, as we now only load it once, it makes sense to log an error
(once) when we fail to read the machine-id.
- previously, loading the machine-id could fail each time. And we
have to somehow handle that error. It seems, the best thing what we
anyway can do, is to log an error once and continue with a fake
machine-id. Here we add a fake machine-id based on the secret-key
or the boot-id. Now obtaining a machine-id can no longer fail
and error handling is no longer necessary.
Also, ensure that a machine-id of all zeros is not valid.
Technically, a machine-id is not an RFC 4122 UUID. But it's
the same size, so we also use NMUuid data structure for it.
While at it, also refactor caching of the boot-id and the secret
key. In particular, fix the thread-safety of the double-checked
locking implementations.
The need for this is the following:
"ipv4.dhcp-client-id" can be specified via global connection defaults.
In absence of any configuration in NetworkManager, the default depends
on the DHCP client plugin. In case of "dhclient", the default further
depends on /etc/dhcp.
For "internal" plugin, we may very well want to change the default
client-id to "mac" by universally installing a configuration
snippet
[connection-use-mac-client-id]
ipv4.dhcp-client-id=mac
However, if we the user happens to enable "dhclient" plugin, this also
forces the client-id and overrules configuration from /etc/dhcp. The real
problem is, that dhclient can be configured via means outside of NetworkManager,
so our defaults shall not overwrite defaults from /etc/dhcp.
With the new device spec, we can avoid this issue:
[connection-dhcp-client-id]
match-device=except:dhcp-plugin:dhclient
ipv4.dhcp-client-id=mac
This will be part of the solution for rh#1640494. Note that merely
dropping a configuration snippet is not yet enough. More fixes for
DHCP will follow. Also, bug rh#1640494 may have alternative solutions
as well. The nice part of this new feature is that it is generally
useful for configuring connection defaults and not specifically for
the client-id issue.
Note that this match spec is per-device, although the plugin is selected
globally. That makes some sense, because in the future we may or may not
configure the DHCP plugin per-device or per address family.
https://bugzilla.redhat.com/show_bug.cgi?id=1640494
This flag is more granular in whether to consider the connection
available or not. We probably should never check for the combined
flag NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST directly, but
always explicitly for the relevant parts.
Also, improve the error message, to indicate whether the device is
strictly unmanaged or whether it could be overruled.
The flags NMDeviceCheckConAvailableFlags and NMDeviceCheckDevAvailableFlags
both control whether a device appears available (either, available in
general, or related to a particular profile).
Also, both flag types strictly increase availability. Meaning: more flags,
more available.
There is some overlap between the flags, however they still have
their own distinct parts.
Improve the mapping from NMDeviceCheckConAvailableFlags to
NMDeviceCheckDevAvailableFlags, by picking exactly the flags
that are relevant.
We should not use GAsyncResult. At least, not for internal API.
It's more cumbersome then helpful, in my opinion. It requires
this awkward async_finish() pattern.
Instead, let the caller pass a suitable callback of the right type.
When the client terminates, we really don't care if it exited cleanly,
with an error or killed by a signal. We expect the client to never
exit and so all these situations are equally bad for us. Introduce a
new TERMINATED state instead of reusing existing FAIL or DONE states,
which are set when receiving particular events from the client.
The @was_active flag indicates that we started DHCP on an assumed
connection. The idea is that if DHCP succeeded before, any failure
must be treated like a renewal failure (and so it should start a grace
period) rather than a failure in getting an initial lease (which fails
the IP method).
When we clean up the DHCP instance, the flag must be reset to FALSE,
otherwise it will be potentially considered for other connections.
The effect of a DHCPv6 failure should depend only on current IP state.
This in the analogous of commit bd63d39252 ("dhcp: fix handling of
failure events") for IPv6.
We already have nm_utils_bin2hexstr() and _nm_utils_bin2hexstr_full().
This is confusing.
- nm_utils_bin2hexstr() is public API of libnm. Also, it has
a last argument @final_len to truncate the string at that
length.
It uses no delimiter and lower-case characters.
- _nm_utils_bin2hexstr_full() does not do any truncation, but
it has options to specify a delimiter, the character case,
and to update a given buffer in-place. Also, like
nm_utils_bin2hexstr() and _nm_utils_bin2hexstr() it can
allocate a new buffer on demand.
- _nm_utils_bin2hexstr() would use ':' as delimiter and make
the case configurable. Also, it would always allocate the returned
buffer.
It's too much and confusing. Drop _nm_utils_bin2hexstr() which is internal
API and just a wrapper around _nm_utils_bin2hexstr_full().
NMAcdManager is a rather simple instance.
It does not need (thread-safe) ref-counting, in fact, having
it ref-counted makes it slighly ugly that we connect a signal,
but never bother to disconnect it (while the ref-counted instance
could outlife the signal subscriber).
We also don't need GObject signals. They have more overhead
and are less type-safe than a regular function pointers. Signals
would make sense, if there could be multiple independent listeners,
but that just doesn't make sense.
Implementing it as a plain struct is less lines of code, and less
runtime over head.
Also drop the possiblitiy to reset the NMAcdManager instance.
It wasn't needed and I think it was buggy because it wouldn't
reset the n-acd instance.
https://github.com/NetworkManager/NetworkManager/pull/213
Kernel complains with:
platform-linux: link: change 10: token: set IPv6 address generation token to ::bbbb
platform-linux: do-change-link[10]: failure changing link: failure 22 (Invalid argument)
if we try to set an IPv6 token in ip_config_merge_and_apply() and we
haven't set accept_ra=1 yet. Since the flag is set when starting
router discovery, ensure that we don't try to set a token before that.
https://github.com/NetworkManager/NetworkManager/pull/214https://bugzilla.redhat.com/show_bug.cgi?id=1560652
In update update_ext_ip_config() we remove from various internal
configurations those addresses and routes that were removed externally
by users.
When the interface is brought down, the kernel automatically removes
routes associated with it and so we should not consider them as
"removed by users".
Instead, keep them so that they can be restored when the interface
comes up again.
device_link_changed() can't use nm_device_update_from_platform_link()
to update the device private fields because the latter overwrites
priv->iface and priv->up, and so the checks below as:
if (info.name[0] && strcmp (priv->iface, info.name) != 0) {
and:
was_up = priv->up;
priv->up = NM_FLAGS_HAS (info.n_ifi_flags, IFF_UP);
...
if (priv->up && !was_up) {
never succeed.
Fixes: d7f7725ae8
Nothing changes practically, as the NMDevice still starts this with
AF_UNSPEC. That is going to change in the following commit.
The ugly part:
priv->concheck_x[0] in few places. I believe we shouldn't be using union
aliasing here, and instead of indexing the v4/v6 arrays by a boolean it
should be an enum. I'm not fixing it here, but I eventually plan to if
this gets an ACK.