When the instance is not running (after creation or after stop), there
is no need to keep the GHashTable around.
Create it when needed (during start) and clear it during stop. This
makes it slightly cheaper to keep a NMLldpListener instance around,
if it's currently not running.
NMDevice already keeps the NMLldpListener around, even after stopping
it. It's not clear whether the instance will be started again, so also
clear the GHashTable. Also, one effect is that if you initially were in
a network with many LLDP neibors, after stop and start, the GHashTable
now gets recreated and may not need to allocate a large internal array
as before.
We already rate limit change events by two seconds. When we notice
that something changed, we call data_changed_schedule().
Previously, that would immediately issue the change notification,
if ratelimiting currently was not in effect. That means, if we happen
go receive two LLDP neighbor events in short succession, then the
first one will trigger the change notification right away, while
the second will be rate limited.
Avoid that by always issue scheduling the change notification in
the background. And if we currently are not rate limited, with
an idle handler with low priority.
This changes the order to what the code did previously, before switching
from GVariantDict to GVariantBuilder. But it changes the actually
serialized order in the variant.
GVariantDict is basically a GHashTable, and during g_variant_dict_end()
it uses a GVariantBuilder to create the variant.
This is totally unnecessary in this case. It's probably unnecessary in
most use cases, because commonly we construct variants in a determined series
of steps and don't need to add/remove keys.
Aside the overhead, GHashTable also does not give a stable sort order,
which seems a pretty bad property in this case.
Note that the code changes the order in which we call
g_variant_builder_add() for the fields in code, to preserve the previous
order that GVariantDict actually created (at least, with my version of
glib).
The intermediate parsing step serves very little purpose.
The only use is to ensure that we always add the keys in a stable
order, but we can easily ensure that otherwise.
We only need to parse them to construct the GVariant. There is
no need to keep them around otherwise.
We still keep LldpAttrs array and don't construct the GVariant right
away. The benefit is that this way while parsing we set the array
fields, and afterwards, when we generate the string dictionary, the
keys are sorted.
Move the parsing of the LLDP attributes to a separate function.
In the next step, we will no longer keep all attribute around
and no longer parse them during lldp_neighbor_new().
One effect is that we can no longer (easily) declare the LLDP message as
invalid, if parsing the attributes fails. That makes IMO more sense,
because we should try to expose what little we could parse, and not
be forgiving to unexpected data. If we wanted, we still could hide such
neighbors entirely from being exposed, but that is not done, because
it seems better to expose the parts that were valid.
We actually only need to parse the attributes while constructing
the GVariant. In a first step decouple the tracking of the parsed
attributes from LldpNeighbor struct. More will follow.
Also, track sd_lldp_neighbor instance directly.
sd_lldp_neighbor is a perfectly reasonable container for keeping
track of the LLDP neighbor information. Just keep a reference to
it, and don't clone the data. Especially since the LLDP library
keeps a reference to this instance as well.
Also, to compare whether two neighbors are the same, it is sufficient
to only consider the raw data. Everything else depends on these fields
anyway.
This is only possible and useful becuase sd_lldp_neighbor is of course
immutable. It wouldn't make sense otherwise, but it also would be bad
design to mutate the sd_lldp_neighbor instances.
This couples our code slightly more to the systemd code, which we usually
try to avoid. But when we move away in the future from systemd LLDP library,
we anyway need to rework this heavily (and then too, we wouldn't want
to clone the data, when we could just share the reference).
Allocating and growing the buffer with realloc isn't really
complicated. Do that instead of using a CList.
Also, if there is only one element, then we can track it in-place.
NM_UTILS_LOOKUP_STR_DEFINE() is implemented via a switch statement.
You'd expect that the compiler could optimize that to plain lookup,
since all indexes are consecutive numbers. Anyway, my compiler doesn't,
so use the array ourself.
Note that NM_UTILS_LOOKUP_STR_DEFINE() is exactly intended to lookup
by enum/integer, if the enum values are not consecutive numbers. It may
not be best, when you can directly use the numbers as lookup index.
VARDICT sounds like it would be a variant of "a{sv}" type. But it
can be really any GVariant. Rename to make the type more generic.
This will be used to also hold a binary variant of type "ay".
Currently the LLDP parsing code uses GVariantBuild, which possibly does not
ensure a stable order of elements. Thus the test may not be stable.
However, that will be fixed very soon.
Yes, fewer lines of code is often better, if that means the code itself is
simpler. Code doesn't get simpler by cramping more in the same line.
Have every value on a separate line.
Also, vertically align the table.
Autoconnect-slaves currently forces an activation of all slaves, even
if there is already an active connection for them. This is bad because
at boot slaves first try to autoconnect, then the autoconnect-slaves
of the master kicks in and disconnects/reactivates them.
The only reason why the forceful reactivation was added was to fix
[1]; in that scenario, a slave connection is already active as
non-slave; then it is updated to be a slave; later, the master with
autoconnect-slaves is manually activated. NetworkManager should detect
that the slave connection must now be activated by autoconnect-slaves.
Add a specific check for such situation, instead of always
reactivating all slaves.
[1] https://bugzilla.redhat.com/show_bug.cgi?id=1845018
Fixes: 4985ca5ada ('manager: allow autoconnect-slaves to reconnect the same connection')
When a device is not marked as unmanaged, but also not actively managed
by NetworkManager, then NetworkManager will generate an in-memory
profile to represent the active state, if the device is up and
configured (with an IP address).
Such profiles are commonly named like "eth0", and they are utterly
confusing to users, because they look as if NetworkManager actually
manages the device, when it really just shows that somebody else configures
the device.
We should express this better in the UI, hence add flags to indicate
that.
In practice, such profiles are UNSAVED, NM_GENERATED, and VOLATILE. But
add an explicit flag to represent that.
https://bugzilla.redhat.com/show_bug.cgi?id=1816202
When there are two patch ports connected, each of them must reference
the other; however they can't be created in a single transaction
because they are part of different bridges (so, different
connections). Therefore, the first patch that gets activated will
always fail with "No usable peer $x exists in 'system' datapath" until
the second patch exists.
In theory we could also match the error message, however this doesn't
seem very robust as the message may slightly change in the future.
Psrse the 802.11 IEs after parsing the security information.
Previously the OWE transition mode flag was potentially removed
in case the security properties changed.
Signed-off-by: David Bauer <mail@david-bauer.net>
Commit 37e7fa38c2 ("nm-supplicant-interface: enable OWE security
when transition mode is available") adds the OWE security flag in
case a valid OWE transtition mode IE is present on the beacon.
It also removes the OWE security flag in case the Iinformation elements
of a beacon are updated and a OWE transition mode IE can't be found.
When a pure OWE AP updates it's Information Elements (e.g. BSS Load
Element), the OWE security flag is falsely removed.
Introduce a new NM_802_11_AP_SEC_KEY_MGMT_OWE_TM security flag and use
it exclusively for OWE transition mode. Don't use the
M_802_11_AP_SEC_KEY_MGMT_OWE security flag on transition-mode APs.
Signed-off-by: David Bauer <mail@david-bauer.net>
Systemd's LLDP client also internally tracks all neighbours, and it thus
already needs a maximum already. For systemd, that is currently 128.
We don't need to implement our own rate limiting on top of that,
because if we wouldn't trust the LLDP client to get this right,
it would be DoS-able already.
Also decrease the number of maximum neighbours from 4k to 128.
Note that already previously we wouldn't ever get more than 128
entries.
nm_keyfile_read() and nm_keyfile_write() will be public API.
As such, it must be flexible and extendible for future needs.
There is already the handler callback that fully solves this
(e.g. a future handler event could request whether a certain
behavior is enabled or not).
As additional possibility for future extension, add a flags
argument. Currently no flags are implemented.
From inside a callback 4 properties are potentially interesting
to all callbacks: the currenty group, key, setting and property-name.
Refactor the code to track these properties in NMKeyfileHandlerData
and distinguish between the property name and the keyfile key.
Setting the error on the callback does not work well from bindings.
Instead, let bindings call a (future) nm_keyfile_handler_data_fail_with_error()
function on the handler_data to indicate failure.
As the keyfile handler callback will become public API, it needs to be
usable via bindings. A plain void pointer is not usable. Instead, add
a new type that can be used via introspection.
This will become public API. The enum for read and write callback
serves very similar purposes. Merge them so that we have fewer
types in the public API.