Commit graph

82 commits

Author SHA1 Message Date
Thomas Haller
36f552c5ca
libnm: move NMSettInfoProperty.to_dbus_including_default flag
The "to_dbus_data" existed for namespacing the properties inside it.
However, such a struct adds overhead due to the alignment that it
enforces. We can share the memory needed for the bitfield by having
them beside each other.
2021-07-16 13:31:59 +02:00
Thomas Haller
9a05db61d6
libnm: drop unused NMSettInfoProperty.gprop_to_dbus_fcn() hook 2021-07-16 13:31:59 +02:00
Thomas Haller
b756e058ac
libnm: implement "direct" properties for compare_fcn() 2021-07-16 13:31:58 +02:00
Thomas Haller
33bd052a87
libnm: special handle "name" properties compare_fcn
All settings have a "name" property. Their compare_fcn() is not interesting
and was already previously ignored. But we should not special handle it via
_nm_setting_property_compare_fcn_default().
2021-07-16 13:31:58 +02:00
Thomas Haller
c7262c2290
libnm: add special ignore function for NMSettInfoPropertType.compare_fcn() 2021-07-16 13:31:58 +02:00
Thomas Haller
243459dc3a
libnm: refactor NMSettingClass.compare_property() to NMSettInfoPropertType.compare_fcn()
NMSettingClass.compare_property() will be dropped.
2021-07-16 13:31:58 +02:00
Thomas Haller
7e7d2d173a
libnm: add compare_fcn() to property meta data
So far, we only have NMSettingClass.compare_property() hook.
The ugliness is that this hook is per-setting, when basically
all implementations only compare one property.

It feels cleaner to have a per-property hook and call that consistently.

In step one, we give all properties (the same) compare_fcn() implementation,
which delegates to the existing NMSettingClass.compare_property().
In a second step, this will be untangled.

There is one problem with this approach: NMSettInfoPropertType grows by
one pointer size, and we have potentially many such types. That should
be addressed by unifying types in the future.
2021-07-16 13:31:57 +02:00
Thomas Haller
56241f328f
libnm: always initialize default values for "direct" properties
We encode the default value "direct" properties in the GParamSpec.
But we also avoid CONSTRUCT properties, because they have an overhead
and they are generally odd for the settings.

So up to now, it was cumbersome to explicitly set the default value,
but it was also error prone.

Avoid that by always initializing the default value for our "direct"
properties.
2021-07-12 13:56:39 +02:00
Thomas Haller
3c801ec4f3
libnm: add direct_offset for uint32 properties
And as example, implement NMSettingVrf.table this way. This also
makes all properties of NMSettingVrf implemened as "direct" properties,
and we can drop the explicit getter/setters.
2021-07-12 13:56:38 +02:00
Thomas Haller
f1cb07e438
libnm: support lookup of property-info by param-spec
We also need to find efficiently the property-info for a given
GParamSpec. Add a lookup index for that.
2021-07-12 13:56:34 +02:00
Thomas Haller
102a1f5c31
libnm: use _nm_setting_property_define_direct_string() 2021-07-12 13:56:33 +02:00
Thomas Haller
7556b4f382
libnm: add direct_offset for string properties
And, as an example used for property "connection.stable-id".
2021-07-12 13:56:32 +02:00
Thomas Haller
233776c2c7
libnm: use _nm_setting_property_define_direct_boolean()
There is a new way how to implement default boolean properties.
Use it.
2021-07-12 13:56:31 +02:00
Thomas Haller
8024279cf7
libnm: add direct_offset for boolean properties
Introduce a new mechanism for how to handle properties generically.

We have NMSettInfoSetting, NMSettInfoProperty and NMSettInfoPropertType
with meta data about settings and their properties.

For example, we have a simple boolean property. Then (usually) we have a
boolean GParamSpec, and a plain boolean field in the NMSetting's private
data. We need very little to get (and convert to keyfile, GVariant),
set (from keyfile, GVariant) and compare this property.
All we need to know, is the GParamSpec and the offset of the bool field.

Introduce a new mechanism for that, and as example implement
NM_SETTING_CONNECTION_AUTOCONNECT property this way.

Note that this patch only changes the to_dbus_fcn() for the boolean
property. But this opens up all kind of further improvements.
What we eventually also can do is replace GObjectClass.get_property()
with a generic variant, that knows how to get and set the property.
2021-07-12 13:56:30 +02:00
Thomas Haller
d6f802abcd
libnm: extend NMSettInfoSetting with an offset to the private data
NMSetting instances either have no private data, they use
g_type_add_class_private(), or they embed the private data in the
NMSetting struct.

In all cases, we can find the private data at a fixed offset. Track that
offset in the NMSettInfoSetting meta data.

This will be useful, because properties really are stored in simple
fields, like a boolean property can be stored in a "bool" field. We will
extend the property meta data to track the offset of this property
field, but we also need to know where the offset starts.
2021-07-12 13:34:40 +02:00
Thomas Haller
dc649d1336
libnm/tests: add test for setting "6lowpan.parent" 2021-07-12 13:34:40 +02:00
Thomas Haller
4e109bacab
clang-format: use "IndentPPDirectives:None" instead of "BeforeHash"
Subjectively, I think this looks better.
2021-07-09 08:49:06 +02:00
Thomas Haller
bc57c79d57
libnm: change behavior for normalizing wireguard/dummy profiles to use ipv6.method=disabled
"ipv6.method=ignore" really exists for historic reasons, from a time when
NetworkManager didn't support IPv6 autoconf and let kernel handle it.

Nowadays, we should choose an explicit mode, like "link-local" or
"disabled".

Let nm_connection_normalize() treat WireGuard and dummy profiles
different and set the IPv6 method to "disabled".
2021-07-08 17:20:15 +02:00
Thomas Haller
ef6b942fd5
libnm/tests: check IP method in test_roundtrip_conversion() 2021-07-08 17:20:14 +02:00
Thomas Haller
f9dc0252db
libnm/tests: add test for normalizing "dummy" connection 2021-07-08 17:20:14 +02:00
Beniamino Galvani
cb5960cef7 all: add a new ipv{4,6}.required-timeout property
Add a new property to specify the minimum time interval in
milliseconds for which dynamic IP configuration should be tried before
the connection succeeds.

This property is useful for example if both IPv4 and IPv6 are enabled
and are allowed to fail. Normally the connection succeeds as soon as
one of the two address families completes; by setting a required
timeout for e.g. IPv4, one can ensure that even if IP6 succeeds
earlier than IPv4, NetworkManager waits some time for IPv4 before the
connection becomes active.
2021-07-05 15:15:44 +02:00
Thomas Haller
09fb7877a9
build: fix linking libnm-log-null into different test programs
We require these, otherwise we can get a linker error about
_nm_utils_monotonic_timestamp_initialized symbol being undefined.
2021-07-05 14:51:27 +02:00
Thomas Haller
668c90dbb8
libnm: fix crash in nm_ip_routing_rule_from_string()
import gi
    gi.require_version("NM", "1.0")
    from gi.repository import NM

    r = NM.IPRoutingRule.from_string('priority 10 type blackhole', NM.IPRoutingRuleAsStringFlags.AF_INET)
    r.to_string(NM.IPRoutingRuleAsStringFlags.NONE)

    r = NM.IPRoutingRule.from_string('priority 10 blackhole', NM.IPRoutingRuleAsStringFlags.AF_INET)
    r.to_string(NM.IPRoutingRuleAsStringFlags.NONE)

    r= NM.IPRoutingRule.from_string('priority 10 bogus', NM.IPRoutingRuleAsStringFlags.AF_INET)
    # CRASH

Fixes: e922404990 ('libnm,core: support "prohibit"/"blackhole"/"unreachable" type routing rules')
2021-06-30 17:13:23 +02:00
Thomas Haller
6ac304b673
trivial: fix code formatting
Fixes: ac090edd87 ('libnm: add type enum for handling gprop differences in to_dbus_fcn')
2021-06-23 14:58:29 +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
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
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
042cd99049
libnm/tests: test consistency for nm_meta_setting_types_by_priority 2021-06-17 17:48:08 +02:00
Thomas Haller
14ec96f262
libnm/tests: avoid coverity warning in test_setting_connection_secondaries_verify()
nm_strvarray_get_strv() returns the input pointer itself, if _secondaries is NULL.
It does so intentionally and correctly to create an artificial empty strv array.

Coverity doesn't like this. Try to workaround the warning:

    Error: ARRAY_VS_SINGLETON (CWE-119): [#def484]
    NetworkManager-1.31.90/src/libnm-core-impl/tests/test-setting.c:4544: address_of: Taking address with "&_secondaries" yields a singleton pointer.
    NetworkManager-1.31.90/src/libnm-core-impl/tests/test-setting.c:4544: identity_transfer: Passing "&_secondaries" as argument 1 to function "nm_strvarray_get_strv", which returns that argument.
    NetworkManager-1.31.90/src/libnm-core-impl/tests/test-setting.c:4544: callee_ptr_arith: Passing "_Generic (nm_strvarray_get_strv(&_secondaries, NULL), char const * const * : (char const * const *)nm_strvarray_get_strv(&_secondaries, NULL), char const ** : (char const * const *)nm_strvarray_get_strv(&_secondaries, NULL), char * const * : (char const * const *)nm_strvarray_get_strv(&_secondaries, NULL), char ** : (char const * const *)nm_strvarray_get_strv(&_secondaries, NULL), void const * : (char const * const *)nm_strvarray_get_strv(&_secondaries, NULL), void * : (char const * const *)nm_strvarray_get_strv(&_secondaries, NULL), char const * const * const : (char const * const *)nm_strvarray_get_strv(&_secondaries, NULL), char const ** const : (char const * const *)nm_strvarray_get_strv(&_secondaries, NULL), char * const * const : (char const * const *)nm_strvarray_get_strv(&_secondaries, NULL), char ** const : (char const * const *)nm_strvarray_get_strv(&_secondaries, NULL), void const * const : (char const * const *)nm_strvarray_get_strv(&_secondaries, NULL), void * const : (char const * const *)nm_strvarray_get_strv(&_secondaries, NULL))" to function "_nm_utils_strv_cmp_n" which uses it as an array. This might corrupt or misinterpret adjacent memory locations.
    # 4542|       G_STMT_END
    # 4543|
    # 4544|->         _assert_secondaries(s_con, (const char *const *) arr->pdata);
    # 4545|
    # 4546|           /* reimplement the normalization that we expect to happen and
2021-06-11 22:42:45 +02:00
Thomas Haller
7d063726c2
libnm/tests: fix compilation error with old gcc not supporting __auto_type
Fixes: 23adeed244 ('glib-aux: use NM_VA_ARGS_FOREACH() to implement NM_HASH_COMBINE_BOOLS()')
2021-06-10 13:28:15 +02:00
Thomas Haller
2b2c818e03
glib-aux/uuid: use NMUuid typed argument for nm_uuid_generate_from_string*()
nm_uuid_generate_from_string*() accepts an optional namespace parameter,
to seed the hashing. This previously was a UUID in string format, so it
first had to be parsed.

Rework the code to pass a NMUuid instance that can be used directly.
Also, as the type_args parameter is always of the same type, change
the argument from a void pointer to "const NMUuid *" pointer.
2021-06-08 08:24:14 +02:00
Thomas Haller
10e5f10f9d
glib-aux/uuid: add NM_UUID_INIT() macro 2021-06-08 08:24:13 +02:00
Thomas Haller
23adeed244
glib-aux: use NM_VA_ARGS_FOREACH() to implement NM_HASH_COMBINE_BOOLS() 2021-06-08 08:24:12 +02:00
Thomas Haller
1ccfde7ee6
libnm/tests: add test for NM_NARG() with 120 parameters 2021-06-08 08:24:11 +02:00
Thomas Haller
3699c31eb1
libnm/tests: add test for normalizing "connection.secondaries" 2021-06-04 09:42:38 +02:00
Thomas Haller
3acf62f8be
libnm: use GArray to track "connection.secondaries" property instead of GSList
GSList requires an additional allocation for the container struct for each
element. Also, it does not have O(1) direct access. It's a pretty bad
data structure, especially if the underlying data is in form of a strv
array.

Use a GArray instead and the nm_strvarray_*() helpers.
2021-06-04 09:29:24 +02:00
Thomas Haller
6f2ae46b37
all: use nm_uuid_is_normalized() for checking valid UUID for "connection.uuid"
"connection.uuid" gets normalized. When we check for a valid UUID, we expect
it to be normalized.
2021-06-04 09:29:23 +02:00
Thomas Haller
5ce91adeff
libnm/trivial: rename _nm_keyfile_equals() to _nm_keyfile_equal() 2021-05-27 09:56:41 +02:00
Thomas Haller
a559950d41
libnm/tests: avoid Coverity warning in test code _do_test_utils_str_utf8safe_unescape()
Error: FORWARD_NULL (CWE-476): [#def435]
    NetworkManager-1.31.5/src/libnm-core-impl/tests/test-general.c:9084: var_compare_op: Comparing "str" to null implies that "str" might be null.
    NetworkManager-1.31.5/src/libnm-core-impl/tests/test-general.c:9105: var_deref_model: Passing null pointer "str" to "strchr", which dereferences it.
    # 9103|           s = nm_utils_str_utf8safe_unescape(str, NM_UTILS_STR_UTF8_SAFE_FLAG_NONE, &str_free_1);
    # 9104|           g_assert_cmpstr(s, ==, expected);
    # 9105|->         if (strchr(str, '\\')) {
    # 9106|               g_assert(str_free_1 != str);
    # 9107|               g_assert(s == str_free_1);
2021-05-26 15:46:00 +02:00
Thomas Haller
6646ee6546
libnm/tests: avoid potential crash in test code test_nm_utils_escaped_tokens()
It causes a Coverity warning, so let's work around it.
2021-05-26 15:46:00 +02:00
Wen Liang
18839361ac
bond: support tlb_dynamic_lb in balance-alb mode
In kernel, `tlb_dynamic_lb` is supported to configure in bonding mode
`balance-alb`. Therefore, add the support in NetworkManager to avoid
undesirable limitation.

Kernel previously had such limitation and it was removed in
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e79c1055749e3183a2beee04a24da378623329c5.

Signed-off-by: Wen Liang <liangwen12year@gmail.com>

https://bugzilla.redhat.com/show_bug.cgi?id=1959934

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/868
2021-05-26 14:57:21 +02:00
Gris Ge
652ddca04c
ethtool: Introducing PAUSE support
Introducing ethtool PAUSE support with:

 * ethtool.pause-autoneg on/off
 * ethtool.pause-rx on/off
 * ethtool.pause-tx on/off

Limitations:
 * When `ethtool.pause-autoneg` is set to true, the `ethtool.pause-rx`
   and `ethtool.pause-tx` will be ignored. We don't have warning for
   this yet.

Unit test case included.

Signed-off-by: Gris Ge <fge@redhat.com>

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/829
2021-05-12 18:04:46 +02:00
Thomas Haller
207cf3d5d4
libnm: normalize "connection.uuid"
For NetworkManager profiles, "connection.uuid" is the identifier of the
profile. It is supposed to be a UUID, however:

- the UUID was not ensured to be all-lower case. We should make sure
  that our UUIDs are in a consistent manner, so that users can rely
  on the format of the string.

- the UUID was never actually interpreted as a UUID. It only was some
  opaque string, that we use as identifier. We had nm_utils_is_uuid()
  which checks that the format is valid, however that did not fully
  validate the format, like it would accept "----7daf444dd78741a59e1ef1b3c8b1c0e8"
  and "549fac10a25f4bcc912d1ae688c2b4987daf444d" (40 hex characters).

Both invalid UUIDs and non-normalized UUID should be normalized. We
don't want to break existing profiles that use such UUIDs, thus we don't
outright reject them. Let's instead mangle them during
nm_connection_normalize().
2021-05-04 15:51:59 +02:00