Commit graph

14355 commits

Author SHA1 Message Date
Thomas Haller
c5e7e2f694
dhcp/trivial: rename "NMDhcpClientFactory.experimental" to "NMDhcpClientFactory.undocumented"
It's not experimental. It's not officially documented. Rename.
2021-06-23 13:11:56 +02:00
Thomas Haller
eb3ef97dd0
dhcp: refactor GType handling for NMDhcpClientFactory
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.
2021-06-23 13:11:56 +02:00
Thomas Haller
524114add7
dhcp: minor cleanup of DHCP plugin factory 2021-06-23 13:11:56 +02:00
Thomas Haller
895b7dd95a
glib-aux: rework NM_HASH_COMBINE_BOOLS() macro to avoid expression statement
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()')
2021-06-23 13:09:24 +02:00
Thomas Haller
1e29a7e66b
std-aux: rework NM_STATIC_ASSERT_EXPR() macro
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.
2021-06-23 13:09:24 +02:00
Thomas Haller
a3eb2c7026
libnm: use _nm_setting_property_define_string() for string NMSetting properties 2021-06-23 12:47:40 +02:00
Thomas Haller
22edf34ba3
libnm: use _nm_setting_property_define_boolean() for boolean NMSetting properties 2021-06-23 12:47:38 +02:00
Thomas Haller
d5c4378cdf
libnm: use new including_default flag and boolean getter for "ethernet.auto-negotiate" property 2021-06-23 12:47:34 +02:00
Thomas Haller
acc3a66bf2
libnm: add flag to control whether to_dbus_fcn() should handle default values
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.
2021-06-23 12:47:33 +02:00
Thomas Haller
e435fdfedf
libnm: extend to_dbus_fcn() property type for efficiently converting string property 2021-06-23 12:47:32 +02:00
Thomas Haller
a832781a8a
libnm: extend to_dbus_fcn() property type for efficiently converting boolean property
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.
2021-06-23 12:47:31 +02:00
Thomas Haller
54cab39ac9
libnm: move gprop_to_dbus_fcn hook to NMSettInfoProperty
For each property we have meta data in form of NMSettInfoProperty.
Each meta data also has a NMSettInfoProperty.property_type
(NMSettInfoPropertType).

The property type is supposed to define common behaviors for properties,
while the property meta data has individual properties. The idea is that
several properties can share the same property-type, and that
per-property meta data is part of NMSettInfoProperty.

The distinction is not very strong, but note that all remaining uses
of NMSettInfoPropertType.gprop_to_dbus_fcn were part of a property
type that was only used for one single property. That lack of
reusability hints to a wrong use.

Move gprop_to_dbus_fcn to the property meta data as a new field
NMSettInfoProperty.to_dbus_data.

Note that NMSettInfoPropertType.gprop_from_dbus_fcn still suffers from
the same problem. But the from-dbus side is not yet addressed.
2021-06-23 12:47:30 +02:00
Thomas Haller
ed57990b58
libnm: change "nm_sett_info_propert_type_mac_address" to use gprop_type for to_dbus_fcn() 2021-06-23 12:47:29 +02:00
Thomas Haller
6d39014660
libnm: change "nm_sett_info_propert_type_strdict" to use gprop_type for to_dbus_fcn() 2021-06-23 12:47:27 +02:00
Thomas Haller
8c0a8a6d9b
libnm: change "nm_sett_info_propert_type_dcb_au" to use gprop_type for to_dbus_fcn() 2021-06-23 12:47:25 +02:00
Thomas Haller
ac090edd87
libnm: add type enum for handling gprop differences in to_dbus_fcn
For GBytes, GEnum, GFlags and others, we need special converters from the
default GObject properties to GVariant.

Previously, those were implemented by providing a special
gprop_to_dbus_fcn hook. But gprop_to_dbus_fcn should move
from NMSettInfoPropertType to NMSettInfoProperty, because it's
usually a per-property meta data, and not a per-property-type meta data.
The difference is whether the meta data can be shared between different
properties (of the same "type).

In these cases, this extra information is indeed part of the type.
We want to have a generic NM_SETT_INFO_PROPERT_TYPE_GPROP() property
(using _nm_setting_property_to_dbus_fcn_gprop()), but then we would like
to distinguish between special cases. So this was fine.

However, I find the approach of providing a gprop_to_dbus_fcn in this
case cumbersome. It makes it harder to understand what happens. Instead,
introduce a new "gprop_type" for the different types that
_nm_setting_property_to_dbus_fcn_gprop() can handle.

This new "gprop_type" is extra data of the property type, so
introduce a new field "typdata_to_dbus".
2021-06-23 12:47:24 +02:00
Thomas Haller
6fc2e03677
libnm: add and use NM_SETT_INFO_PROPERT_TYPE_*_INIT() macros
The advantage is that we use similar macros for initializing the
static structs like

   const NMSettInfoPropertType nm_sett_info_propert_type_cloned_mac_address;

and the ad-hoc locations that use NM_SETT_INFO_PROPERT_TYPE().

The former exist for property types that are used more than once.
The latter exist for convenience, where a property type is implemented
at only one place.

Also, there are few direct references to _nm_setting_property_to_dbus_fcn_gprop().
all users use NM_SETT_INFO_PROPERT_TYPE_GPROP() or
NM_SETT_INFO_PROPERT_TYPE_GPROP_INIT().
2021-06-23 12:13:41 +02:00
Thomas Haller
69597a67c1
libnm: add and use NM_SETT_INFO_PROPERT_TYPE_DBUS() macro 2021-06-23 12:13:40 +02:00
Thomas Haller
c161439b73
libnm: let all property types implement to_dbus_fcn() handler
If a property can be converted to D-Bus, then always set the
to_dbus_fcn() handler. The only caller of to_dbus_fcn() is
property_to_dbus(), so this means that property_to_dbus()
has no more default implementation and always delegates to
to_dbus_fcn().

The code is easier to understand if all properties implement
to_dbus_fcn() the same way.

Also, there is supposed to be a split between NMSettInfoProperty (info about
the property) and NMSettInfoPropertType (the type). The idea is that
each property (obviously) requires its distinct NMSettInfoProperty, but
they can share a common type implementation.
With NMSettInfoPropertType.gprop_to_dbus_fcn that is often violated because
many properties that implement NMSettInfoPropertType.gprop_to_dbus_fcn
require a special type implementation. As such, gprop_to_dbus_fcn should
be part of the property info and not the property type. The first step towards
that is unifying all properties to use to_dbus_fcn().
2021-06-23 12:13:39 +02:00
Thomas Haller
c54be51f99
libnm: add NM_SETTING_PARAM_NONE define
This completes other NM_SETTING_PARAM_* flags.
2021-06-23 12:13:39 +02:00
Thomas Haller
4065158491
libnm: drop unused parameter "ignored_default" from property_to_dbus() 2021-06-23 12:13:39 +02:00
Thomas Haller
21638c54b0
libnm: simplify assertions for valid NMSettInfoProperty 2021-06-23 12:13:39 +02:00
Thomas Haller
8081e39ab6
libnm: expose internal helper nm_utils_hwaddr_to_dbus() 2021-06-23 12:13:38 +02:00
Thomas Haller
87229b22ae
glib-aux: add NM_G_PARAM_SPEC_GET_DEFAULT_STRING() helper 2021-06-23 12:13:38 +02:00
Thomas Haller
e2defd0115
glib-aux: add nm_g_variant_singleton_s_empty() helper 2021-06-23 12:13:38 +02:00
Thomas Haller
edb31252cc
glib-aux: add nm_g_variant_singleton_b() helper 2021-06-23 12:13:27 +02:00
Thomas Haller
48d345d62f
libnm/docs: better explain "connection.autoconnect{,-priority}" 2021-06-22 13:06:38 +02:00
Thomas Haller
c6559b04c2
std-aux/glib-aux: minor cleanup of nm_ip_addr_*()/nm_utils_addr_family_*()
- let nm_ip_addr_is_null() work for unaligned addresses.

- drop redundant nm_assert_addr_family().

- move code around.
2021-06-22 09:47:44 +02:00
Thomas Haller
9452d69465
config: avoid cloning string during nm_config_data_get_connection_default() et al.
NMConfigData is immutable and with the previous commit are the strings
already cached internally. There is no need to clone it.

Of course, the callers must not assume that the string stays alive after
a config reload (SIGHUP), where the NMConfigData might change. So they
are not always alive, but long enough for all callers to avoid cloning
the string.
2021-06-21 17:23:53 +02:00
Thomas Haller
2f9ab1d528
config: add lookup index for _match_section_infos_lookup()
Previously, we would call g_key_file_get_string(), which requires
two hash lookups (one for the group and one for the key).

We can do better. Especially since NMConfigData is immutable, it's
simple to build a lookup index of the values we have and then do binary
search.

Note that we call nm_config_data_get_connection_default() and similar
API *a lot*, so this is measurable.
2021-06-21 17:23:53 +02:00
Thomas Haller
b929caa95c
core: use nm_config_data_get_device_config_int64() for getting integer setting 2021-06-21 17:23:53 +02:00
Thomas Haller
a6c9f2518e
config: add nm_config_data_get_device_config_int64() helper 2021-06-21 17:23:53 +02:00
Thomas Haller
42ba464380
glib-aux: cleanup nm_utils_named_value_clear_with_g_free() implementation 2021-06-21 17:23:53 +02:00
Thomas Haller
1441b04bba
dhcp/systemd: ignore FORCERENEW requests for DHCPV4 to workaround CVE-2020-13529
The FORCERENEW reqest was not authenticated (because neither rfc3118 nor
rfc6704) is implemented. That is a potential security issue.

As workaround, patch the source to ignore those requests. Note that also
nettools implementation ignores FORCERENEW requests, so if there would
be a need to handle them, then it would be important to improve the
nettools code (which is the main implementation).

The systemd DHCP plugin is no longer used by default. The user explicitly has to
enable it via the undocumented "[main].dhcp=systemd" option in NetworkManager.conf.
Hence, this change is probably not very important either way.

See-also: https://bugzilla.redhat.com/show_bug.cgi?id=1959398
See-also: https://github.com/systemd/systemd/issues/16774
https://bugzilla.redhat.com/show_bug.cgi?id=1966123
CVE-2020-13529

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/898
2021-06-21 16:24:55 +02:00
Thomas Haller
58c3af1a7d
libnm: pre-allocate buffer in _nm_sett_info_property_override_create_array()
The buffer created here is only temporary to construct the property info
by _nm_setting_class_commit_full(). We can afford to allocate more than
necessary, if we thereby avoid several reallocations.
2021-06-21 15:08:35 +02:00
Beniamino Galvani
3c55db886a device: prefer IPv6 not-deprecated addresses for hostname lookup
In presence of a IPv6 deprecated address and a non-deprecated one, the
latter will be used by kernel for new connections according to RFC
6724 section 5 (Source Address Selection). Prefer it also to lookup a
hostname via reverse DNS.

While at it, also prefer non-link-local addresses over link-local
ones.
2021-06-21 10:08:27 +02:00
Beniamino Galvani
ff84a4736d libnm-platform: add NM_PLATFORM_MATCH_WITH_ADDRSTATE_DEPRECATED
Add a new flag to match deprecated addresses. An address is deprecated
when its preferred lifetime has expired but its valid lifetime has
not.

Address deprecation is one of the criteria for source address
selection in IPv6. For IPv4 the deprecation doesn't have any
real effect.

Note that this commit changes the behavior of
nm_ip_config_get_first_address(WITH_ADDRSTATE_NORMAL), since now
deprecated addresses are not returned. However this should not impact
existing callers since they either:

 - request a IPv6 (WITH_ADDRTYPE_LINKLOCAL | WITH_ADDRSTATE_NORMAL)
   address; IPv6 link-local addresses are supposed to have infinite
   lifetimes;

 or

 - request a IPv6 (WITH_ADDRTYPE_NORMAL | WITH_ADDRSTATE__ANY)
   address.
2021-06-21 10:08:27 +02:00
Beniamino Galvani
ca31cbbc74 core: add nm_ip_config_find_first_address()
Replace nm_ip6_config_find_first_address() with a version generic for
IPv4 and IPv6.
2021-06-21 10:08:27 +02:00
Beniamino Galvani
376c7f8315 libnm-platform: add nm_platform_ip_address_match()
Replace nm_platform_ip6_address_match() with a version generic for
IPv4 and IPv6.
2021-06-21 10:08:27 +02:00
Thomas Haller
06296f7c3c
libnm: belatedly export nm_ip_routing_rule_[gs]et_uid_range() symbols 2021-06-21 10:00:20 +02:00
Thomas Haller
eb8e55c822
version: add 1.34 macros 2021-06-21 10:00:20 +02:00
Beniamino Galvani
637a45e25b policy: prefer IPv4 to determine the hostname
When determining the hostname, it is preferable to evaluate devices in
a predictable order to avoid that the hostname changes between
different boots.

The current order is based first on hostname priority, then on the
presence of a best default route, and then on activation order.

The activation order is not a very strong condition, as it is
basically useless for devices that are autoactivated at boot.

As we already prefer IPv4 over IPv6 within the same connection, also
prefer it when 2 connections have the same priority and the same
default route status, to achieve better predictability.

https://bugzilla.redhat.com/show_bug.cgi?id=1970335
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/895
2021-06-21 08:53:42 +02:00
Thomas Haller
877d2b236f
core: avoid checking sort order for cached settings list
We now have a cached list of NMSettingsConnection instances,
sorted by their autoconnect priority.

However, the sort order nm_settings_connection_cmp_autoconnect_priority()
depends on various properties of the connection:

 - "connection.autoconnect" and "connection.autoconnect-priority"
 - the timestamp
 - "connection.uuid"

These properties almost never change, so it's a waste that every call
to nm_settings_get_connections_sorted_by_autoconnect_priority() needs
to check whether the sort order is still satisfied.

We can do better by tracking when the sort order might have been
destroyed and only check in those (much fewer) cases.

Note that we end up calling nm_settings_get_connections_sorted_by_autoconnect_priority()
a lot, so this makes a difference.
2021-06-18 11:20:30 +02:00
Thomas Haller
252e4a676b
core: cache GVariant for result of GetSettings()
The GetSettings() call is not the only place where we convert a
NMConnection to D-Bus. However it is one of the most prominent ones
with a measurable performance overhead.

The connection seldom changes, so it makes sense to cache it.

Note that GetSettings() is the only caller that specifies an option,
thus it's the only caller that converts a NMConnection to variant
in this particular way. That means, other callers don't benefit from
this caching and we could not cache the variant in the NMConnection
instance itself, because those callers use different parameters.
2021-06-17 17:49:44 +02:00
Thomas Haller
cea52c7cbd
libnm: add nm_connection_serialization_options_equal() helper 2021-06-17 17:48:16 +02:00
Thomas Haller
92daaff7d1
glib-aux: add NM_STRV_EMPTY_CC() helper macro 2021-06-17 17:48:15 +02:00
Thomas Haller
60957a4c8a
libnm: add helper functions for emitting signals in NMConnection
Not very useful, but it seems nicer to read. They anyway can be
inlined. After all, naming and structure is important and the places
where we emit signals are important. By having well-named helper
functions, these places are easier to find and reason about.
2021-06-17 17:48:14 +02:00
Thomas Haller
e7b5650eff
core: add nm_settings_get_connection_sorted_by_autoconnect_priority()
Turns out, we call nm_settings_get_connection_clone() *a lot* with sort order
nm_settings_connection_cmp_autoconnect_priority_p_with_data().

As we cache the (differently sorted) list of connections, also cache
the presorted list. The only complication is that every time we still
need to check whether the list is still sorted, because it would be
more complicated to invalidate the list when an entry changes which
affects the sort order. Still, such a check is usually successful
and requires "only" N-1 comparisons.
2021-06-17 17:48:13 +02:00
Thomas Haller
1f09e13f43
core: add nm_settings_connection_cmp_autoconnect_priority_with_data() helper 2021-06-17 17:48:13 +02:00
Thomas Haller
f51d3862f9
glib-aux: add nm_utils_ptrarray_is_sorted() helper 2021-06-17 17:48:12 +02:00