We have two GKeyfile files (timestamps and seen-bssids).
When a profile was deleted while NetworkManager was running, then
entries were removed from these keyfiles. But if a profile disappeared
while NetworkManger was stopped, then those UUIDs piled up.
This also happens if you have temporary connections in /run and reboot.
We need a way to garbage collect entries that are no longer relevant.
As the keyfile databases only get loaded once from disk, we will prune
all UUIDs for which we have no more connection loaded, on the first time
we write out the files again.
Note what this means: if you "temporarily" remove a connection profile
(without NetworkManager noticing) and restore it later, then the additional
information might have been pruned. There is no way how NetworkManager
could know that this UUID is coming back. The alternative is what we did
before: pile them up indefinitely. That seems more problematic.
Previously, there was no limit how many seen-bssids are tracked.
That seems problematic, also because there is no API how to get
rid of an excessive list of entries.
We should limit the number of entries. Add an (arbitrary) limit
of 30.
But this means that we drop the surplus of entries, and for that it
seems important to keep the newest, most recently seen entries.
Previously, entries were merely sorted ASCIIbetically. Now, honor
their order (with most recently seen first).
Also, normalize the BSSIDs. From internal code, we should only get
normalize strings, but when we load them from disk, they might be bogus.
As we might cut of the list, we don't want that invalid entries
cut of valid ones. And of course, invalid entries make no sense at
all.
ifcfg-rh plugin never stored the seen bssid list to file, and
keyfile no longer does, and it's no longer parsed from GVariant.
So there is actually no way how anything could be set here.
The seen-bssids should only be populate from
"/var/lib/NetworkManager/seen-bssids". Nowhere else.
"wifi.seen-bssid" is an unusual property, therefore very ugly due to the
inconsistency.
It is not a regular user configuration that makes sense to store to
disk or modify by the user. It gets populated by the daemon, and
stored in "/var/lib/NetworkManager/seen-bssids" file.
As such, how to convert this to/from D-Bus needs special handling.
This means, that the to/from D-Bus functions will only serialize the
property when the seen-bssids are specified via
NMConnectionSerializationOptions, which is what the daemon does.
Also, the daemon ignores seen-bssids when parsing the variant.
This has the odd effect that when the client converts a setting to
GVariant, the seen-bssids gets lost. That means, a conversion to GVariant
and back looses information. I think that is OK in this case, because the
main point of to/from D-Bus is not to have a lossless GVariant representation
of a setting, but to transfer the setting via D-Bus between client and
daemon. And transferring seen-bssids via D-Bus makes only sense from the daemon
to the client.
"seen-bssids" primarily gets stored to "/var/lib/NetworkManager/seen-bssids",
it's not a regular property.
We want this property to be serialized/deserialized to/from GVariant,
because we expose these settings on the API like a property of the
profile. But it cannot be modified via nmcli, it cannot be stored
to ifcfg files, and it makes not sense to store it to keyfile either.
Stop doing that.
On RHEL-8.5, s390x with gcc-8.5.0-2.el8, we get a compiler warning:
$ CFLAGS='-O2 -Werror=maybe-uninitialized' meson build
...
cc -Isrc/libndhcp4-private.a.p -Isrc -I../src -Isubprojects/c-list/src -I../subprojects/c-list/src -Isubprojects/c-siphash/src -I../subprojects/c-siphash/src -Isubprojects/c-stdaux/src -I../subprojects/c-stdaux/src -fdiagnostics-color=always -pipe -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -std=c11 -g -D_GNU_SOURCE -O2 -Werror=maybe-uninitialized -fPIC -fvisibility=hidden -fno-common -MD -MQ src/libndhcp4-private.a.p/n-dhcp4-c-connection.c.o -MF src/libndhcp4-private.a.p/n-dhcp4-c-connection.c.o.d -o src/libndhcp4-private.a.p/n-dhcp4-c-connection.c.o -c ../src/n-dhcp4-c-connection.c
../src/n-dhcp4-c-connection.c: In function ‘n_dhcp4_c_connection_dispatch_io’:
../src/n-dhcp4-c-connection.c:1151:17: error: ‘type’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
uint8_t type;
^~~~
https://github.com/nettools/n-dhcp4/pull/24
nm-cloud-setup automatically detects routes, addresses and rules and configures them
on the device using the emphermal Reapply() API. That is, it does not modify the
existing profile (on disk), but changes the runtime configuration only.
As such, it used to wipe otherwise statically configured IP addresses, routes and
rules. That seems unnecessary. Let's keep the configuration from the (persistent)
configuration.
There is of course the problem that nm-cloud-setup doesn't really
understand the existing IP configuration, and it can only hope that
it can be meaningfully combined with what nm-cloud-setup wants to
configure. This should cover most simple cases, for more complex setups,
the user probably should disable nm-cloud-setup and configure the
network explicitly to their liking.
https://bugzilla.redhat.com/show_bug.cgi?id=1971527https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/893
This function is badly named, because it has no NMHostnameManager self
argument. It's just a simple function that entirely operates on a string
argument.
Move it away from "nm-hostname-manager.h" to "libnm-glib-aux/nm-shared-utils.h".
Hostname handling is complicated enough. Simple string validation
functions should not obscure the view on the complicated parts.
Using the guint source ID always requires an additional hash lookup
during removal to find the real source instance. Use instead the
underlying GSource instance.
Searching over all sources in order to remove them is not what we want
to do. If you think you need these functions, instead keep track of the
GSource instances yourself.
I think this is non-obvious API, and should be pointed out. As we don't
really have a good place for this comment, the place is a bit unmotivated.
Still, add a comment.
We somehow need to encode an NMSettingEthtool instance that has all
options unset. Previously, that would result in no "$ETHTOOL_OPTS"
variable and thus the reader would loose a previously existing setting.
Hack it by writing a bogus
ETHTOOL_OPTS="-A $IFACE"
line.
It just seems ugly to call g_getenv() repeatedly. Environment variables
must not change (in a multi-threaded program after other threads start),
so determine the mode once and cache it.
For the umpteenth time: it is not ifcfg-rh writers decision to decide
what are valid configurations and only persist settings based on
some other settings.
If s390-options would only be allowed together with subchannels, then
this is alone nm_connection_verify()'s task to ensure.
Reproduce with
$ nmcli connection add type ethernet autoconnect no con-name zz ethernet.s390-options bridge_role=primary
Related: https://bugzilla.redhat.com/show_bug.cgi?id=1935842
Fixes: 16bccfd672 ('core: handle s390 options more cleanly')
A failure to cancel something is not worth a warning. It probably
just means that no operation was in progress. In my logs I always
see a warning:
CODE_FILE=src/core/supplicant/nm-supplicant-interface.c
CODE_LINE=391
MESSAGE=<warn> [1624517233.8822] sup-iface[a22b181a321ffd9b,9,wlan0]: call-p2p-cancel: failed with P2P cancel failed
Downgrade this to trace level.
This is actually trying *too* hard to prevent DNS leaks, breaking normal
expected use of split DNS. Let systemd-resolved handle sending our DNS
queries to the right place instead.
It's true that NetworkManager is trying to emulate the behavior of
wg-quick here, and wg-quick uses 'resolvconf -x' to attempt to set
"exclusive" DNS. But with systemd-resolved this is implemented by
setting a ~. routing domain for the Wireguard interface. That is a
*really* big hammer already, since Domain=~. overrides +DefaultRoute,
ensuring most DNS queries can only go to other interfaces with Domain=~.
NetworkManager follows systemd-resolved's recommended convention by only
applying Domain=~. to other "privacy VPNs" since 1.26.6. Setting DNS
priority only prevents *domain-specific* "leaks", which are almost
always desired. For example, it prevents using both the Wireguard VPN
and a corporate VPN at the same time.
Note that all of the justification behind !688 applies here as well.
See-also: https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/688https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/585https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/901
When we are a client in the group we may be assigned an address by the
group owner. Use this address if it is available, but only if we are in
AUTO configuration mode.
We have nm_object_get_client() property that returns a reference
to the NMClient instance. This is actually useful, because if
the function returns %NULL, it means that the object was removed
from the cache.
On the other hand, the user cannot subscribe to notifications when this
happens. Well, there are otherwise pointless signals like
NM_CLIENT_DEVICE_REMOVED, which we wouldn't need if we had a general
mechanism for NMObject instances.
Add a GObject property "client", which is just that mechanism.
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/902
In NetworkManager.conf, we can only configure one "[main].dhcp="
for both address families. Consequently, NMDhcpClientFactory
represents also both address families. However, most plugins
don't support IPv4 and IPv6 together.
Thus, if a plugin does not support an address family, we fallback
to the implementation of the "internal" plugin.
Slightly rework the code how that is done. Instead of having
a "get_type()" and "get_type_per_addr_family()" callback, have
an IPv4 and IPv6 getter.
clang 3.4.2-9.el7 dislikes expressions in the form
int v;
struct {
typeof(({ v; })) _field;
} x;
error: statement expression not allowed at file scope
typeof( ({ v; }) ) _field;
^
That is, if the argument to typeof() is an expression statement. But this is
what
nm_hash_update_val(&h, ..., NM_HASH_COMBINE_BOOLS(...))
expands to. Rework NM_HASH_COMBINE_BOOLS() to avoid the expression statement.
We still have the static assertion for the size of the return type.
We no longer have the _nm_hash_combine_bools_type typedef. It really
wasn't needed, and the current variant is always safe without it.
Fixes: 23adeed244 ('glib-aux: use NM_VA_ARGS_FOREACH() to implement NM_HASH_COMBINE_BOOLS()')
Replace NM_STATIC_ASSERT_EXPR() by NM_STATIC_ASSERT_EXPR_1() and
NM_STATIC_ASSERT_EXPR_VOID(). NM_STATIC_ASSERT_EXPR_VOID() can be
used as an expression that returns void (that is, a simple statement).
On the other hand, NM_STATIC_ASSERT_EXPR_1() itself retuns
a compile time constant of int value 1. The latter is useful, because
we can use the 1 to combine static assertions in expressions that
are themself compile time constants, like
#define STATIC_CHECK_AND_GET(cond, value) \
(NM_STATIC_ASSERT_EXPR_1(cond) ? (value) : (value))
This is itself a compile time constant if value is a compile
time constant. Also, it does the compile time check that "cond"
is true.
Usually, properties that are set to their default are not serialized on
D-Bus. That is, to_dbus_fcn() returns NULL.
In some cases, we explicitly want to always serialize the property. For
example, if we changed behavior and the libnm default value changed.
Then we want that the message on D-Bus is always clear about the used
value and not rely on the default value on the receiving side.
Most of our NMSetting properties are based around GObject properties,
and thus the tooling to convert a NMSetting to/from GVariant consists
of getting/setting a GValue.
We can do better.
For most of such properties we also define a C getter function, which
we can call with less overhead. All we need is to hook the C getter with
the property meta data.
As example, implement it for "connection.autoconnect".
The immediate goal of this is to reduce the overhead of to_dbus. But
note that also for comparison of two properties, there is the default
implementation which is used by the majority of properties. This
implementation converts the properties first to GVariant (via
to_dbus_fcn) and then compares the variants. What this commit also does,
is to hook up the property meta data with the C-getters. This is one step
towards also more efficiently compare properties using the naive C
getters. Likewise, the keyfile writer use g_object_get_property().
It also could do better.