Commit graph

85 commits

Author SHA1 Message Date
Thomas Haller
e6a33c04eb
all: make "ipv6.addr-gen-mode" configurable by global default
It can be useful to choose a different "ipv6.addr-gen-mode". And it can be
useful to override the default for a set of profiles.

For example, in cloud or in a data center, stable-privacy might not be
the best choice. Add a mechanism to override the default via global defaults
in NetworkManager.conf:

  # /etc/NetworkManager/conf.d/90-ipv6-addr-gen-mode-override.conf
  [connection-90-ipv6-addr-gen-mode-override]
  match-device=type:ethernet
  ipv6.addr-gen-mode=0

"ipv6.addr-gen-mode" is a special property, because its default depends on
the component that configures the profile.

- when read from disk (keyfile and ifcfg-rh), a missing addr-gen-mode
  key means to default to "eui64".
- when configured via D-Bus, a missing addr-gen-mode property means to
  default to "stable-privacy".
- libnm's ip6-config::addr-gen-mode property defaults to
  "stable-privacy".
- when some tool creates a profile, they either can explicitly
  set the mode, or they get the default of the underlying mechanisms
  above.

  - nm-initrd-generator explicitly sets "eui64" for profiles it creates.
  - nmcli doesn' explicitly set it, but inherits the default form
    libnm's ip6-config::addr-gen-mode.
  - when NM creates a auto-default-connection for ethernet ("Wired connection 1"),
    it inherits the default from libnm's ip6-config::addr-gen-mode.

Global connection defaults only take effect when the per-profile
value is set to a special default/unset value. To account for the
different cases above, we add two such special values: "default" and
"default-or-eui64". That's something we didn't do before, but it seams
useful and easy to understand.

Also, this neatly expresses the current behaviors we already have. E.g.
if you don't specify the "addr-gen-mode" in a keyfile, "default-or-eui64"
is a pretty clear thing.

Note that usually we cannot change default values, in particular not for
libnm's properties. That is because we don't serialize the default
values to D-Bus/keyfile, so if we change the default, we change
behavior. Here we change from "stable-privacy" to "default" and
from "eui64" to "default-or-eui64". That means, the user only experiences
a change in behavior, if they have a ".conf" file that overrides the default.

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

See-also: https://github.com/coreos/fedora-coreos-tracker/issues/907

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1213
2022-06-29 07:38:48 +02:00
Thomas Haller
dab2ee8ac5
all: suppress wrong gcc-12 warning "-Wdangling-pointer"
gcc-12.0.1-0.8.fc36 is annoying with false positives.
It's related to g_error() and its `for(;;) ;`.

For example:

    ../src/libnm-glib-aux/nm-shared-utils.c: In function 'nm_utils_parse_inaddr_bin_full':
    ../src/libnm-glib-aux/nm-shared-utils.c:1145:26: error: dangling pointer to 'error' may be used [-Werror=dangling-pointer=]
     1145 |                     error->message);
          |                          ^~
    /usr/include/glib-2.0/glib/gmessages.h:343:32: note: in definition of macro 'g_error'
      343 |                                __VA_ARGS__);         \
          |                                ^~~~~~~~~~~
    ../src/libnm-glib-aux/nm-shared-utils.c:1133:31: note: 'error' declared here
     1133 |         gs_free_error GError *error = NULL;
          |                               ^~~~~
    /usr/include/glib-2.0/glib/gmessages.h:341:25: error: dangling pointer to 'addrbin' may be used [-Werror=dangling-pointer=]
      341 |                         g_log (G_LOG_DOMAIN,         \
          |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      342 |                                G_LOG_LEVEL_ERROR,    \
          |                                ~~~~~~~~~~~~~~~~~~~~~~~
      343 |                                __VA_ARGS__);         \
          |                                ~~~~~~~~~~~~
    ../src/libnm-glib-aux/nm-shared-utils.c:1141:13: note: in expansion of macro 'g_error'
     1141 |             g_error("unexpected assertion failure: could parse \"%s\" as %s, but not accepted by "
          |             ^~~~~~~
    ../src/libnm-glib-aux/nm-shared-utils.c:1112:14: note: 'addrbin' declared here
     1112 |     NMIPAddr addrbin;
          |              ^~~~~~~

I think the warning could potentially be useful and prevent real bugs.
So don't disable it altogether, but go through the effort to suppress it
at the places where it currently happens.

Note that NM_PRAGMA_WARNING_DISABLE_DANGLING_POINTER macro only expands
to suppressing the warning with __GNUC__ equal to 12. The purpose is to
only suppress the warning where we know we want to. Hopefully other gcc
versions don't have this problem.

I guess, we could also write a NM_COMPILER_WARNING() check in
"m4/compiler_options.m4", to disable the warning if we detect it. But
that seems too cumbersome.
2022-02-21 19:50:52 +01:00
Ana Cabral
27c33d15ef keyfile: do not write empty string list properties
https://bugzilla.redhat.com/show_bug.cgi?id=2022623
2022-02-11 12:26:01 +01:00
Thomas Haller
61ff2b03df
libnm: add direct strv type for NMSetting and use it for "match.interface-name"
G_TYPE_STRV is the last property type in NMSetting that is implemented
by directly accessing the GObect property. Note that we have lots of
override, non-default implementations that still use GObject properties,
but I am talking here about properties that don't have a special
implementation and use a G_TYPE_STRV GObject property.

Add a "direct" implementation also for strv arrays.

The advantage is that we no longer call g_value_get() for various
operations, which requires a deep-copy of the strv array. The other
advantage is that we will get a unified approach for implementing strv
properties. In particular strv arrays need a lot of code to implement,
and most settings do it differently. By adding a general mechanism,
this code (and behavior) can be unified.

Showcase it on "match.interface-name".
2022-02-10 22:30:27 +01:00
Thomas Haller
6f0e22a64a
libnm/tests: fix maybe-uninitialized warning in "test-setting"
In function '_nm_auto_g_free',
      inlined from 'test_tc_config_tfilter_matchall_mirred' at src/libnm-core-impl/tests/test-setting.c:2955:24:
  ./src/libnm-glib-aux/nm-macros-internal.h:58:1: error: 'str' may be used uninitialized [-Werror=maybe-uninitialized]
     58 | NM_AUTO_DEFINE_FCN_VOID0(void *, _nm_auto_g_free, g_free);
        | ^
  src/libnm-core-impl/tests/test-setting.c: In function 'test_tc_config_tfilter_matchall_mirred':
  src/libnm-core-impl/tests/test-setting.c:2955:24: note: 'str' was declared here
   2955 |     gs_free char      *str;
        |                        ^
  lto1: all warnings being treated as errors
  lto-wrapper: fatal error: gcc returned 1 exit status
2022-01-20 21:53:23 +01:00
Thomas Haller
419be57dbc
libnm: support direct string properties as NMRefString
Several properties like "connection.type" are enum-like and only take a few
known values. We can use a NMRefString to share their instances.

Currently nm_setting_duplicate() does not yet explicitly handle direct properties.
But it should, because it can handle them more efficiently. If it would do that, it
would be very cheap to "copy" a NMRefString. But even with the current implementation
will the result be deduplicated.
2022-01-18 16:22:38 +01:00
Thomas Haller
72e523830c
libnm: refactor some NMSetting to use direct properties for string 2022-01-18 16:22:28 +01:00
Thomas Haller
20d6793065
libnm: refactor some NMSetting to use direct properties for uint32 2022-01-18 16:22:25 +01:00
Thomas Haller
208df83491
libnm: refactor some NMSetting to use direct properties for int32 2022-01-18 16:22:24 +01:00
Thomas Haller
822042d9f9
libnm: add hook for setting direct string property
We want that our properties have little special cases and follow a
few common behaviors. For example, we have string properties, and those
should mostly behave the same (e.g. by being "direct-string"
properties).

That is already not fully enough, because we have slightly different
behaviors. For example, we have string properties that should have their
whitespace stripped, that should be ascii case down converted, that
should be normalized IP or MAC addresses. So far, that was expressed via
simple fields in NMSettInfoProperty, like NMSettInfoProperty's
direct_set_string_ascii_strdown field.

But that is not enough. In particular, for "wireguard.private-key" we
perform a different kind of normalization (base64 parsing, and taking
care not to leak secret in memory). It seems to special to add a boolean
flag "direct_set_string_wireguard_private_key".

Instead, add a hook that can cover that.

We need a hook, because we want one setter implementation throughout. Commonly,
we have at least two setters: the GObject set_property() and from D-Bus.
Both should call into the same underlying implementation, to avoid code
duplication. For that, the tweaked behavior must be "down", that is at
the deepest point in the call stack where we set the string. That's why
we need the hook. The alternative would be two special implementation
for GObject and D-Bus setters (and in the future we might add setters
from keyfile).
2022-01-18 16:22:22 +01:00
Thomas Haller
710c54760c
libnm: add direct property type "int64" 2022-01-18 16:22:18 +01:00
Thomas Haller
5e7400c832
libnm: add flag to map zero to NULL in _nm_utils_ipaddr_canonical_or_invalid()
This seems a questionable thing to do, and should be made clearer by
having a parameter (that makes you think about what is happening here).

Also, the normalization for vxlan.remote does not perform this mapping,
so the parameter is there so that the approach can handle both flavors.
2022-01-18 16:22:17 +01:00
Thomas Haller
1f58244268
libnm: let direct string property support AF_UNSPEC for normalizing IP addresses 2022-01-18 16:22:16 +01:00
Thomas Haller
16bf47f8ca
libnm: automatically clear secret string for direct string properties
Let's sprinkle some snake ointment.

This is questionable, because we copy secrets all over the place where
we their deallocation (and clearing) is not in our control. For example,
the GValue setter/getter copies the string (but does not clean the
secret). Also, when converting the property to a GVariant, we won't
clear it. So this does not catch a lot of cases.

Still, if we can with relative ease avoid leaking the string at some
places, do it.
2022-01-18 16:22:15 +01:00
Thomas Haller
360d5f0998
libnm: add direct_set_string_strip flag for direct string property 2022-01-18 16:22:13 +01:00
Thomas Haller
4010d75922
libnm: refactor some NMSetting to use direct properties for enum/flags
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1033
2021-12-24 11:14:22 +01:00
Thomas Haller
615221a99c format: reformat source tree with clang-format 13.0
We use clang-format for automatic formatting of our source files.
Since clang-format is actively maintained software, the actual
formatting depends on the used version of clang-format. That is
unfortunate and painful, but really unavoidable unless clang-format
would be strictly bug-compatible.

So the version that we must use is from the current Fedora release, which
is also tested by our gitlab-ci. Previously, we were using Fedora 34 with
clang-tools-extra-12.0.1-1.fc34.x86_64.

As Fedora 35 comes along, we need to update our formatting as Fedora 35
comes with version "13.0.0~rc1-1.fc35".
An alternative would be to freeze on version 12, but that has different
problems (like, it's cumbersome to rebuild clang 12 on Fedora 35 and it
would be cumbersome for our developers which are on Fedora 35 to use a
clang that they cannot easily install).

The (differently painful) solution is to reformat from time to time, as we
switch to a new Fedora (and thus clang) version.
Usually we would expect that such a reformatting brings minor changes.
But this time, the changes are huge. That is mentioned in the release
notes [1] as

  Makes PointerAligment: Right working with AlignConsecutiveDeclarations. (Fixes https://llvm.org/PR27353)

[1] https://releases.llvm.org/13.0.0/tools/clang/docs/ReleaseNotes.html#clang-format
2021-11-29 09:31:09 +00:00
Thomas Haller
04b4982d3c
libnm: refactor some NMSetting to use direct properties
"direct" properties are the latest preferred way to implement GObject
base properties. That way, the property meta data tracks the
"direct_type" and the offset where to find the data in the struct.

That way, we can automatically

- initialize the default values
- free during finalize
- implement get_property()/set_property()

Also, the other settings operations (compare, to/from D-Bus) are
implemented more efficiently and don't need to go through
g_object_get_property()/GValue API.
2021-11-08 22:23:16 +01:00
Thomas Haller
2aa1fdd2bf
libnm: add direct property type "bytes" 2021-11-04 20:25:19 +01:00
Thomas Haller
37967ad717
libnm: add direct property type "enum" 2021-11-04 20:25:19 +01:00
Thomas Haller
1059b60873
libnm: add direct property type "uint64" 2021-11-04 20:25:19 +01:00
Thomas Haller
093f434cd0
libnm: add direct property type "flags"
"flags" are a g_param_spec_flags() and correspond to G_TYPE_FLAGS type.
They are internally stored as guint, and exported on D-Bus as "u" (32 bit
integer).
2021-11-04 20:25:19 +01:00
Thomas Haller
aeb2426e88
libnm: change default value for "dcb.app-fcoe-mode" property
String properties in libnm's NMSetting really should have NULL as a
default value. The only property that didn't, was "dcb.app-fcoe-mode".

Change the default so that it is also NULL.

Changing a default value is an API change, but in this case probably no
issue. For one, DCB is little used. But also, it's not clear who would
care and notice the change. Also, because previously verify() would reject
a NULL value as invalid. That means, there are no existing, valid profiles
that have this value set to NULL.  We just make NULL the default, and
define that it means the same as "fabric".

Note that when we convert integer properties to D-Bus/GVariant, we often
omit the default value. For string properties, they are serialized as
"s" variant type. As such, NULL cannot be expressed as "s" type, so we
represent NULL by omitting the property. That makes especially sense if
the default value is also NULL. Otherwise, it's rather odd. We change
that, and we will now always express non-NULL value on D-Bus and let
NULL be encoded by omitting the property.
2021-11-04 20:25:18 +01:00
Thomas Haller
d805b9ae51
libnm/tests: always check expected default value for string properties in test_setting_metadata() 2021-11-04 20:25:18 +01:00
Thomas Haller
e38ddb52e3
all: rename nmtst_* functions that are used by the daemon
The name prefix "nmtst_*" is reserved for test helpers and stub
function. Such functions should not be in the actual build artifacts,
like the NetworkManager binary.

Instead, nmtst_connection_assert_unchanging() is not a test helper. It
is a assertion function that is only enabled with NM_MORE_ASSERTS
builds. That's different.

Rename.

In other words,

  $ nm src/core/NetworkManager src/libnm-client-impl/.libs/libnm.so | grep nmtst

should give no results.
2021-09-08 18:33:43 +02:00
Gris Ge
9958510f28
bond: add support of queue_id of bond port
Introduced `NMSettingBondPort` to hold the new setting class with single
property `NM_SETTING_BOND_PORT_QUEUE_ID`.

For dbus interface, please use `bond-port` as setting name and
`queue-id` as property name.

Unit test cases for ifcfg reader and writer included.

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

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

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/952
2021-08-26 23:04:31 +02:00
Thomas Haller
b06aed2d66
libnm/tests: check property meta data for secrets 2021-08-02 10:01:04 +02:00
Thomas Haller
4c3aac899e
all: unify and rename strv helper API
Naming is important, because the name of a thing should give you a good
idea what it does. Also, to find a thing, it needs a good name in the
first place. But naming is also hard.

Historically, some strv helper API was named as nm_utils_strv_*(),
and some API had a leading underscore (as it is internal API).

This was all inconsistent. Do some renaming and try to unify things.

We get rid of the leading underscore if this is just a regular
(internal) helper. But not for example from _nm_strv_find_first(),
because that is the implementation of nm_strv_find_first().

  - _nm_utils_strv_cleanup()                 -> nm_strv_cleanup()
  - _nm_utils_strv_cleanup_const()           -> nm_strv_cleanup_const()
  - _nm_utils_strv_cmp_n()                   -> _nm_strv_cmp_n()
  - _nm_utils_strv_dup()                     -> _nm_strv_dup()
  - _nm_utils_strv_dup_packed()              -> _nm_strv_dup_packed()
  - _nm_utils_strv_find_first()              -> _nm_strv_find_first()
  - _nm_utils_strv_sort()                    -> _nm_strv_sort()
  - _nm_utils_strv_to_ptrarray()             -> nm_strv_to_ptrarray()
  - _nm_utils_strv_to_slist()                -> nm_strv_to_gslist()
  - nm_utils_strv_cmp_n()                    -> nm_strv_cmp_n()
  - nm_utils_strv_dup()                      -> nm_strv_dup()
  - nm_utils_strv_dup_packed()               -> nm_strv_dup_packed()
  - nm_utils_strv_dup_shallow_maybe_a()      -> nm_strv_dup_shallow_maybe_a()
  - nm_utils_strv_equal()                    -> nm_strv_equal()
  - nm_utils_strv_find_binary_search()       -> nm_strv_find_binary_search()
  - nm_utils_strv_find_first()               -> nm_strv_find_first()
  - nm_utils_strv_make_deep_copied()         -> nm_strv_make_deep_copied()
  - nm_utils_strv_make_deep_copied_n()       -> nm_strv_make_deep_copied_n()
  - nm_utils_strv_make_deep_copied_nonnull() -> nm_strv_make_deep_copied_nonnull()
  - nm_utils_strv_sort()                     -> nm_strv_sort()

Note that no names are swapped and none of the new names existed
previously. That means, all the new names are really new, which
simplifies to find errors due to this larger refactoring. E.g. if
you backport a patch from after this change to an old branch, you'll
get a compiler error and notice that something is missing.
2021-07-29 10:26:50 +02:00
Thomas Haller
3775f4395a
all: drop unnecessary casts from nm_utils_strv_find_first()
And, where the argument is a GPtrArray, use
nm_strv_ptrarray_find_first() instead.
2021-07-29 09:33:50 +02:00
Thomas Haller
c1157d73ad
libnm: add from_dbus_fcn for direct NMSettingIPConfig.gateway property 2021-07-23 17:02:04 +02:00
Thomas Haller
e6562493ef
libnm: add from_dbus_fcn for direct properties
There is a quest to move away from the GObject/GValue based setters.
Add _nm_setting_property_from_dbus_fcn_direct(), which can parse
the GVariant and use the direct_type to set the property.

Note that for backward compatibility, we still need
_nm_property_variant_to_gvalue() to convert alternative GVariant
types to the destination value. This means, as before, on the D-Bus
API a property of a certain type can be represented as various D-Bus
types.
2021-07-23 17:02:04 +02:00
Thomas Haller
6d07afaa8d
libnm: implement special setter for direct string property for ip address
This is a normalization employed by NMSettingIPConfig.gateway.

Also rework NMSettingIPConfig.set_property() to no longer assert against
valid input. We want to pass there untrusted strings from D-Bus,
asserting is a horrible idea. Instead, either normalize the string or
keep the invalid text that will be rejected by verify().
2021-07-23 17:02:03 +02:00
Thomas Haller
0c7286a855
libnm: implement special setter for direct string property for mac address 2021-07-23 17:02:03 +02:00
Thomas Haller
96657b1556
libnm: implement special setter for direct string property via g_ascii_strdown() 2021-07-23 17:02:03 +02:00
Thomas Haller
e399fda04c
libnm: add nm_sett_info_propert_type_direct_int32 property type 2021-07-23 17:02:02 +02:00
Thomas Haller
82e9f43289
libnm: add nm_sett_info_propert_type_direct_mac_address
A MAC address is a relatively common "type". The GObject property is of type string,
but the D-Bus type is a bytestring ("ay"). We will need a special NMSettInfoPropertType.

Note that like most implementations, the from-dbus implementation still is based
on GObject setters. This will change in the future.

Also note that the previous compare function was
_nm_setting_property_compare_fcn_default(). That is, it used to convert
the property to GVariant and compare those. The conversion to GVariant
in that case normalizes the string (e.g. it is case insensitive). Also,
only properties could be compared which were also convertible to D-Bus
(which is probably fine, because there is no guarantee the profiles that
don't verify can be compared).

The code now uses the direct comparison of the strings. That mostly
preserves the case-insensitivity of the previous comparison, because
the property setters for mac addresses all use
_nm_utils_hwaddr_canonical_or_invalid() to normalize the strings.
This is subtle, but still correct. Note that this will improve later,
by ensuring that the property setters for mac addresses automatically
perform the right normalization.
2021-07-23 17:02:01 +02:00
Thomas Haller
77d2c13e21
libnm: always set from_dbus_fcn() property hook
When looking at a property, it should always be clear how it is handled.
Also the "default" action should be an explicit hook.

Add _nm_setting_property_from_dbus_fcn_gprop() and set that as
from_dbus_fcn() callback to handle the "default" case which us
build around g_object_set_property().

While this adds lines of code, I think it makes the code easier to
understand. Basically, to convert a GVariant to a property, now all
properties call their from_dbus_fcn() handler, there is no special casing.
And the gprop-hook is only called for properties that are using
_nm_setting_property_from_dbus_fcn_gprop(). So, you can reason about
these two functions at separate layers.
2021-07-16 13:31:59 +02:00
Thomas Haller
b34220a084
libnm: explicitly ignore to-dbus for "name" property
NM_SETTING_NAME is also a GObject property, but it's
not supposed to be serialized to/from D-Bus. It also
is irrelevant for comparison.

Hence, it's operations are all NOPs. Make an explicit property type for
that case instead of checking the GParamSpec flags.
2021-07-16 13:31:59 +02:00
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