nm_hash_siphash42() uses a randomized seed like nm_hash*(). In this case,
we want to always generate the same fake timestamp, based on the host-id.
In practice, it doesn't really matter, because this is only the fallback
path for something gone horribly wrong already.
c_siphash_init() requires a 16 bytes array. That is cumbersome to use.
We have NM_HASH_SEED_16() macro for helping with that. It's still
cumbersome.
Most of the time, the caller just wants to pick an arbitrarily chosen,
fixed number. Add NM_HASH_SEED_16_U64() which takes a number and gives
a 16 seed array. The argument is in host endianness, but the resulting
seed array has it encoded in big endianness, to be architecture
independent.
Calling getpwuid_r() is cumbersome, because it has a separate passwd and
string buffer, and you shall retry, when the buffer is too small.
Extract nm_getpwuid() for that. This one always allocates a suitable
buffer, that the caller can free.
This will allow callers to get the full passwd struct. It will also
allow callers to avoid the additional strdup() of nm_utils_uid_to_name(),
when we don't need a clone of the string.
Most profiles don't have "connection.permissions" set. Avoid resolving the
UID to the name via getpwuid() (in nm_auth_is_subject_in_acl()), until we
know that we require it.
I think GSource* is preferable, because it's more type-safe than the
guint numbers. Also, g_source_remove() only works with
g_main_context_default(), while g_source_detach() of a GSource pointer
works with any GMainContext (so it's more general, even if we in this
case only have sources attached to g_main_context_default()).
Handling GSource* pointers is possibly also faster, since it saves one
extra g_main_context_find_source_by_id() -- on the other hand, tracking
the pointer costs 8 bytes while tracking the guint only costs 4 bytes.
Whether it's faster is unproven, but possibly it is. In any case it's
not an argument against using pointers.
Anyway. Update another usage of source-ids to use GSource pointers.
This is also the pattern that "checkpatch.pl" suggests.
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1774
CC src/libnm-core-impl/libnm_core_impl_la-nm-setting.lo
src/libnm-core-impl/nm-setting.c: In function '_nm_setting_class_commit':
src/libnm-core-impl/nm-setting.c:339:41: error: unused variable 'i' [-Werror=unused-variable]
339 | guint i;
| ^
src/libnm-core-impl/nm-setting.c: At top level:
src/libnm-core-impl/nm-setting.c:168:1: error: '_nm_sett_info_property_find_in_array' defined but not used [-Werror=unused-function]
168 | _nm_sett_info_property_find_in_array(const NMSettInfoProperty *properties,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
Fixes: 2dd5b065a8 ('libnm: drop special casing G_TYPE_STRV from _nm_setting_class_commit()')
What we sort is very static, the names of properties in
NMSettingConnection. We know that the list contains no two identical
names. There were already assertions for that, just rework them a bit to
make the code clearer.
Previously, _nm_setting_class_commit() required that the "name" of a
NMSettInfoProperty is unset, when the property also has a "param_spec".
_nm_setting_class_commit() would then as first iterate over all
properties, and set the name.
In practice, all callers only initialize NMSettInfoProperty via
_nm_properties_override_gobj(). Now, let _nm_properties_override_gobj()
set the "name" right away.
Now _nm_setting_class_commit() will instead assert that the name is always
set, and that the caller takes care of that. That means, we have less to
do in _nm_setting_class_commit() (assertions aside).
Direct properties are automatically cleaned up by the base class
(_finalize_direct()). No need to duplicate that. The point of
the direct property implementation is to free us from this repeated
cumbersome steps (and forgetting this step without a direct property
would not be only unnecessary, but erroneous).
There are no such properties left. They now all use
_nm_setting_property_define_gprop_strv_oldstyle() and the
properties_override array already contains the properties.
This simplifies _nm_setting_class_commit() and moves logic away.
Note that most of the code in _nm_setting_class_commit() is only asserts
for consistency.
Since "properties_override" now contains all properties, it doesn't
really "override" any default and the name is bad. Anyway.
Use _nm_setting_property_define_gprop_strv_oldstyle() for all existing
(remaining) G_TYPE_STRV properties.
The benefit is that the properties_override array already lists the
property, and we don't need special hacks in _nm_setting_class_commit()
to initialize those properties.
Also, this style is discouraged. We can now easier find all properties
that should be reworked.
This will be used for adding G_TYPE_STRV properties. This is a legacy
approach, new properties should use _nm_setting_property_define_direct_strv(),
which is more efficient and where the meta-data knows more about the
strv property.
Will be used next.
For settings with many properties, pre-allocate a larger buffer via
_nm_sett_info_property_override_create_array_sized().
The buffer is larger than needed, so when we add more properties it
still works. In any case, GArray will grow automatically, so getting
this wrong is not fatal (just suboptimal).
The goal is to have the properties_overrides already pre-populated with
all properties. Then we will be able to drop special cases from
_nm_setting_class_commit().
Some Applications require to explicitly enable or disable EEE.
Therefore introduce EEE (Energy Efficient Ethernet) support with:
* ethtool.eee on/off
Unit test case included.
Signed-off-by: Johannes Zink <j.zink@pengutronix.de>
When creating default connections automatically, we check if udev has
set the NM_AUTO_DEFAULT_LINK_LOCAL_ONLY variable, and if so, we create
the connection with method=link-local. It was checked only for ethernet
connection type, which works fine because it's the only device type that
we create connections automatically for.
However, link-local connections are not specific to Ethernet, and if we
add auto-default connections for more devices in the future we should
honor this configuration too. Do it from nm-device, but only if the
device class has defined a "new_default_connection" method so the
behaviour is identical as the current one, but will be used by future
implementors of this method too.
See-also: https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1780https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1779
If ID_NET_MANAGED_BY= attribute is set, we have an indication who is
responsible for the device. If this is set to anything but
"org.freedesktop.NetworkManager", then the device is unmanaged.
The effect is the same as setting NM_UNMANAGED= attribute. NM_UNMANAGED=
takes precedence over this setting.
See-also: https://github.com/systemd/systemd/issues/29768
See-also: https://github.com/systemd/systemd/pull/29782
We honored "NM_AUTO_DEFAULT_LINK_LOCAL_ONLY" udev property, for when we
generate a "Wired connection 1" (aka the "auto-default connection").
Systemd now also honors and may set ID_NET_AUTO_LINK_LOCAL_ONLY for
a similar purpose. Honore that too.
The NM specific variable still is preferred, also because "NM_AUTO_DEFAULT_LINK_LOCAL_ONLY"
is about something very NetworkManager specific (controlling "Wired connection 1").
Maybe one day, we should drop "data/90-nm-thunderbolt.rules" and only
rely on what systemd provides. But not yet.
See-also: https://github.com/systemd/systemd/pull/29767https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/1413
Historically, the NMSetting types were in public headers. Theoretically,
that allowed users to subtype our classes. However in practice that was
impossible because they lacked required access to internal functions to
fully create an NMSetting class outside of libnm. And it also was not
useful, because you simply cannot extend libnm by subtyping a libnm
class. And supporting such a use case would be hard and limit what we can
do in libnm.
Having GObject structs in public headers also require that we don't
change it's layout. The ABI of those structs must not change, if anybody
out there was actually subclassing our GObjects.
In libnm 1.34 (commit e46d484fae ('libnm: hide NMSetting types from
public headers')) we moved the structs from headers to internal.
This would have caused a compiler error if anybody was using those
struct definitions. However, we still didn't change the ABI/layout so
that we didn't break users who relied on it (for whatever reason).
It doesn't seem there were any affected user. We waited long enough.
Change internal ABI.
No longer use g_type_class_add_private(). Instead, embed the private
structs directly (_NM_GET_PRIVATE()) or indirectly
(_NM_GET_PRIVATE_PTR()) in the object.
The main benefit is for debugging in the debugger, where we can now
easily find the private data. Previously that was so cumbersome to be
effectively impossible.
It's also the fastest possible way, since NM_SETTING_*_GET_PRIVATE()
literally resolves to "&self->_priv" (plus static asserts and
nm_assert() for type checking).
_NM_GET_PRIVATE() also propagates constness and requires that the
argument is a compatible pointer type (at compile time).
Note that g_type_class_add_private() is also deprecated in glib 2.58 and
replaced by G_ADD_PRIVATE(). For one, we still don't rely on 2.58. Also,
G_ADD_PRIVATE() is a worse solution as it supports a usecase that we
don't care for (public structs in headers). _NM_GET_PRIVATE() is still
faster, works with older glib and most importantly: is better for
debugging as you can find the private data from an object pointer.
For NMSettingIPConfig this is rather awkward, because all direct
properties require a common "klass->private_offset". This was however
the case before this change. Nothing new here. And if you ever touch
this and do something wrong, many unit tests will fail. It's almost
impossible to get wrong, albeit it can be confusing to understand.
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1773
If a ovs interface has the cloned-mac-address property set, we pass
the desired MAC to ovsdb when creating the db entry, and openvswitch
will eventually assign it to the interface.
Note that usually the link will not have the desired MAC when it's
created. Therefore, currently we also change the MAC via netlink
before proceeding with IP configuration. This is important to make
sure that ARP announcements, DHCP client-id, etc. will use the correct
MAC address.
This doesn't work when using the "netdev" (userspace) datapath, as the
attempts to change the MAC of the tun interface via netlink fail,
leading to an activation failure.
To properly handle both cases in the same way, adopt a different
strategy: now we don't set the MAC address explicitly via netlink but
we only wait until ovs does that.
The code to determine if we are using the netdev datapath is logically
separated from the code to start IP configuration; move it to its own
function to make the code easier to follow.
The deactivation can happen while we are waiting for the ifindex, and
it can happen via two code paths, depending on the state. For a
regular deactivation, method deactivate_async() is called. Otherwise,
if the device goes directly to UNMANAGED or UNAVAILABLE, deactivate()
is called. We need to make sure that signal and source handlers are
disconnected, so that they are not called at the wrong time.
Fixes: 99a6c6eda6 ('ovs, dpdk: fix creating ovs-interface when the ovs-bridge is netdev')
nm_g_array_index() performs additional nm_assert() checks for
correctness.
In this case, it's pretty clear that the assertion will hold and that
the code is correct. Note that most of the time when having assertions,
we expect that they hold. Since nm_assert() is disabled in release
build, arguing that an assertion holds is not a strong argument against
having the assert (they are always supposed to hold, quite obviously so!).
The reason to change is that we should use the wrappers that perform
additional checks. Especially when the additional checks are nm_assert()
or static-asserts, as they are not present in release builds. To find
how well we are doing in this regard we can check `git grep -w
g_array_index`. If that gives many uses of the unchecked function, then
we cannot manually check them all to be really obviously correct.
Instead, we should not use g_array_index() and trivially see that all
array accesses are guarded by assertions.
"checkpatch.pl" also recommends against g_array_index().
If the device is being disconnected for a user request, at the moment
the active connection goes to state DEACTIVATED through the following
transitions, independently of the reason for the disconnection:
- state: DEACTIVATING, reason: UNKNOWN
- state: DEACTIVATED, reason: DEVICE_DISCONNECTED
For VPNs, a disconnection is always user-initiated, and the active
connection states emitted are:
- state: DEACTIVATING, reason: USER_DISCONNECTED
- state: DEACTIVATED, reason: USER_DISCONNECTED
This difference poses problems for clients that want to handle device
and VPNs in the same way, especially because WireGuard is implemented
as a device, but is logically a VPN.
Let NMActRequest translate the USER_REQUESTED device state reason to
USER_DISCONNECTED active connection state reason, in case of
disconnection.
This is an API change, but the previous behavior of reporting generic
uninformative reasons seems a bug. See for example
nmc_activation_get_effective_state(), which inspects the AC state
reason and in case it's generic (DEVICE_DISCONNECTED), it considers
the device state instead.
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/1405
NMActiveConnection implements method device_state_changed() that
re-emits device state changes as convenience for subclasses. Add the
reason for the state change to the handler, as it will be used in the
next commit.
This reverts commit 05c31da4d9.
In the linked commit the callback was made repeating on the assumption
that forward progress would result in the callback getting canceled in
cb_data_complete. However, this assumption does not hold since a timeout
callback does not guarantee completion (or error out) of a request.
curl tweaked some internals in v8.4.0 and started giving 0 timeouts, and
a repeating callback is firing back-to-back without making any progress
in doing so.
Revert the change and make the callback non-repeating again.
Fixes: 05c31da4d9 ('connectivity: don't cancel curl timerfunction from timeout')
"skip_repeated" sounds as if the function would only drop duplicate
elements that follow each other (in which case, the operation would be
O(n)). But it does search the entire array to prevent duplicates (resulting
in O(n^2)). Rename the argument "skip_repeated" to "no_duplicates"
to make that clearer.
Also, rename "skip_{empty,duplicates}" to "no_{empty,duplicates}". The
function removes those elements from the list, so "skip" is a bit
misleading too.