Commit graph

58 commits

Author SHA1 Message Date
Thomas Haller
a1ab9d9e1c
libnm: use NMRefString for nm_connection_get_path()
NMConnection is an interface, implemented by NMSimpleConnection and
NMRemoteConnection.

For the most part, an NMConnection is only the content of the profile
(the settings). The "path" of the connection refers to the D-Bus path,
and wouldn't really make sense of the NMConnection interface or the
NMSimpleConnection type.

As such, the daemon (which only uses NMConnection and
NMSimpleConnection) never sets the path. Only libnm does.

NMClient uses NMRefString extensively for the D-Bus interface and the
path is already internalized. Take advantage of that. It is very likely,
that we are able to share the path instance in libnm at which point it
makes sense to use NMRefString.

Also, during nm_simple_connection_new_clone(), we can just take another
reference instead of cloning the string.
2022-10-06 13:43:33 +02:00
Thomas Haller
d75bfd3a3d
libnm: move optimized NM_IS_{SIMPLE,}CONNECTION() to internal header
We already redefine those checks to optimize for NMSimpleConnection.
Which, in particular when libnm-core is used by the daemon, is the only
implementation of the NMConnection interface.

Move those to the private header file. No need to keep it private to
"nm-connection.c".
2022-10-03 17:54:57 +02:00
Thomas Haller
28cb407056
libnm: rework lookup of private data for NMConnection of NMSimpleConnection
NMConnection is an interface, and as such has no data itself.

In practice, there are only two implementations of this interface,
NMSimpleConnection and NMRemoteConnection. The latter only exists
in libnm, not the daemon.

Thus, lookup of the private data is already optimized for
NMSimpleConnection instances via _nm_simple_connection_private_offset.

Use the same mechanism also for NMSimpleConnection itself.
2022-10-03 17:54:56 +02: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
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
710c54760c
libnm: add direct property type "int64" 2022-01-18 16:22:18 +01:00
Ana Cabral
f0cb75f669 trivial: fix typos 2022-01-10 22:48:30 +00: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
989a6911ba
libnm: always finalize direct properties in NMSetting base class
Certain properties need to release memory when destroying the NMSetting.
For "direct" properties, we have all the information we need to do that
generically in the NMSetting base class. In practice, this only concerns
string properties.

See _finalize_direct() in "nm-setting.c".

However, if the NMSetting base class takes care of freeing the strings,
then the subclasses must not also unref the variable (to avoid double free).
Previously, subclasses had to opt-in for the base class to indicate that
they are fine with that.

Now, let the base class always handle it. We only need to make sure that
classes that implement direct string properties don't also try to free
the values during destruction.
2021-11-04 20:25:19 +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
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
Thomas Haller
77421ba1be
libnm: use macros function arguments for NMSettInfoPropertType
These functions tend to have many arguments. They are also quite som
boilerplate to implement the hundereds of properties we have, while
we want that properties have common behaviors and similarities.

Instead of repeatedly spelling out the function arguments, use a macro.

Advantages:

- the usage of a _NM_SETT_INFO_PROP_*_FCN_ARGS  macro signals that this
  is an implementation of a property. You can now grep for these macros
  to find all implementation. That was previously rather imprecise, you
  could only `git grep '\.to_dbus_fcn'` to find the uses, but not the
  implementations.
  As the goal is to keep properties "similar", there is a desire to
  reduce the number of similar implementations and to find them.

- changing the arguments now no longer will require you to go through
  all implementations. At least not, if you merely add an argument that
  has a reasonable default behavior and does not require explicit
  handling by most implementation.

- it's convenient to be able to patch the argument list to let the
  compiler help to reason about something. For example, the
  "connection_dict" argument to from_dbus_fcn() is usually unused.
  If you'd like to find who uses it, rename the parameter, and
  review the (few) compiler errors.

- it does save 573 LOC of boilerplate with no actual logic or useful
  information. I argue, that this simplifies the code and review, by
  increasing the relative amount of actually meaningful code.

Disadvantages:

- the user no longer directly sees the argument list. They would need
  cscope/ctags or an IDE to jump to the macro definition and conveniently
  see all arguments.

Also use _nm_nil, so that clang-format interprets this as a function
parameter list. Otherwise, it formats the function differently.
2021-08-02 10:01:03 +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
ed8e098c30
libnm: add from_dbus_fcn for direct mac-address properties 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
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
a9ef71eb4a
libnm: pass full property meta data to from_dbus_fcn() hook 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
b756e058ac
libnm: implement "direct" properties for compare_fcn() 2021-07-16 13:31:58 +02:00
Thomas Haller
dee29e0c1c
libnm: add _nm_setting_compare_flags_check() helper 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
b78fb1c615
libnm: drop NMSettingClass.compare_property() 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
d8292d462b
libnm: pass around property_info instead of property_idx in NMSetting API
Various NMSetting API would accept a property_idx parameter. Together
with the NMSettInfoSetting instance, this was useful to find the actual
NMSettInfoProperty instance.

The idea was, to provide the most of the functionality. That is, if you
might need the property_idx too, you had it -- after all, the
property_info you could lookup yourself.

However,

- literally zero users care about the property_idx. The care about
  the property_info.

- if the user really, really required the property_idx, then it
  is a given that it can be easily computed by

     (property_info - sett_info->property_infos)
2021-07-16 13:31:57 +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
27621dde45
libnm: add generic cleanup function to finalize NMSetting
If all settings would be strictly be implemented as "direct" properties,
we could call this from NMSetting.finalize() and be done with it.

As it is, for now we cannot, so it's still cumbersome.
2021-07-12 13:56:37 +02:00
Thomas Haller
69db8a462a
libnm: add generic GObject property getter/setter
If we only have simple, direct properties, then we have all the
information we need for a generic get_property()/set_property()
implmenentation.
2021-07-12 13:56:35 +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
03dc5ad391
libnm: let NMSettingIPConfigPrivate be tracked by subclasses
For our property meta data handling we require that all the meta data is
associated with one GType.

NMSettingIPConfig is a parent class of NMSettingIP[46]Config. Note that
we already have _nm_sett_info_property_override_create_array_ip_config()
because the meta data must be initialized together at one place.

We will require that we can find the offset for properties based on one
offset per type. That is cumbersome, if NMSettingIPConfigPrivate is
private itself.

Simplify that, by internally sharing NMSettingIPConfigPrivate and let
the subclasses embed the private data in their own private data.

Optimally we would simply embed the private struct as field into
NMSettingIPConfig. But that would be an ABI change as that struct
was public before 1.32. Don't change ABI for now, so we have to
awkwardly place it into the subclasses private data.
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
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
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
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