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
(cherry picked from commit 6f0e22a64a)
(cherry picked from commit 6329f1db5a)
(cherry picked from commit d3fdb854f9)
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.
(cherry picked from commit cb5960cef7)
(cherry picked from commit 08ce20481c)
Before there was a licensing conflict between the keyfile code
(libnm-keyfile) and libnm. The latter would require LGPL-2.1+ while
keyfile code was GPL-2.0+.
Consequently we were linking libnm-keyfile into the daemon, but not in
libnm.so.
This conflict has been resolved and keyfile API is part of libnm.so.
There is no more need to build a separate (intermediary) library. Merge
them.
This also makes sense because keyfile code needs access to private code
from libnm-core. It is closely tied to libnm-core, so that building them
separate makes no sense (anymore).
Our cast macros (like NM_AUTH_SUBJECT()) are plain C pointer casts,
unless when building with more asserts enabled.
Still, they are unnecessary and even their ability to check the type
(with more asserts) is not needed, because we must trust glib's
g_object_new() to return reasonable objects. That is a basic
requirement, that we don't need to assert against.
Also, in the majority of cases we don't do this either.
We want to use this by "shared/nm-platform", which should have
no dependency on "libnm-core".
Move "libnm-core/nm-ethtool-utils.h" to "libnm/nm-ethtool-utils.h" so
that it is only used by libnm. This file contains the defines for
the option names.
Also, symlink "libnm/nm-ethtool-utils.h" as "shared/nm-base/nm-ethtool-utils-base.h".
We want to use the same defines also internally. Since they are both
public API (must be in libnm) and should be in "shared/nm-base", this
is the way.
We want to use these defines for option names also in "shared/nm-base"
(and in turn in "shared/nm-platform), which cannot include "libnm-core".
However, they are also public API of libnm.
To get this done, in a first step, move these defines to a new header
"libnm-core/nm-ethtool-utils.h".
Since now the name "nm-ethtool-utils.h" is taken, also rename
nm-libnm-core-intern files.
Currently src/platform depends on libnm-core. libnm-core is large
optimally we have a better separation between our code. That means
libnm-core does not depend on platform and vice versa.
However, nm-platform re-uses some enums from libnm-core for internal code.
To avoid that dependency, add _NMSettingWiredWakeOnLan as a duplicate to
nm-base/nm-base.h. nm-base can both be used by libnm-core, nm-platform
and src/platform.
The only problem is that NMSettingWiredWakeOnLan is also part of public
API of libnm. It means, we must duplicate the enum. But with several
static assertions in unit tests I think that is not a problem to do.
Enums can also be negative (contrary to Flags). Fix the parsing.
$ nmcli connection modify "$PROFILE" connection.llmnr -1
Error: failed to modify connection.llmnr: invalid option '-1', use one of [default,no,resolve,yes].
Currently libnm headers include <linux/if_{ether,infiniband,vlan}.h>.
These are public headers, that means we drag in the linux header to all
users of <NetworkManager.h>.
Often the linux headers work badly together with certain headers from libc.
Depending on the libc version, you have to order linux headers in the right
order with respect to libc headers.
We should do better about libnm headers. As a first step, assume that
the linux headers don't get included by libnm, and explicitly include
them where they are needed.
The underscore somehow indicated that these would be an internal
function. Which they are in the sense that they are in "shared/nm-glib-aux/".
But they part of our internal helper functions, and in our code base
their use is no discouraged or "private.
Also, next I'll replace the function call with a macro, so, I will
have a need for the underscore name.
Rename.
Previously, both nm_setting_connection_add_permission() and the GObject
property setter would merely assert that the provided values are valid
(and otherwise don't do anything). That is bad for handling errors.
For example, we use the property setter to initialize the setting from
keyfile and GVariant (D-Bus). That means, if a user provides an invalid
permissions value, we would emit a g_critical() assertion failure, but
otherwise ignore the configuration. What we instead need to do is to
accept the value, and afterwards fail verification. That way, a proper error
message can be generated.
$ mcli connection add type ethernet autoconnect no ifname bogus con-name x connection.permissions 'bogus:'
(process:429514): libnm-CRITICAL **: 12:12:00.359: permission_new: assertion 'strchr (uname, ':') == NULL' failed
(process:429514): libnm-CRITICAL **: 12:12:00.359: nm_setting_connection_add_permission: assertion 'p != NULL' failed
Connection 'x' (2802d117-f84e-44d9-925b-bfe26fd85da1) successfully added.
$ $ nmcli -f connection.permissions connection show x
connection.permissions: --
While at it, also don't track the permissions in a GSList. Tracking one
permission in a GSList requires 3 allocations (one for the user string,
one for the Permission struct, and one for the GSList struct). Instead,
use a GArray. That is still not great, because GArray cannot be embedded
inside NMSettingConnectionPrivate, so tracking one permission also
requires 3 allocations (which is really a fault of GArray). So, GArray
is not better in the common case where there is only one permissions. But even
in the worst case (only one entry), GArray is no worse than GSList.
Also change the API of nm_setting_connection_add_permission().
Previously, the function would assert that the arguments are in
a certain form (strcmp (ptype, "user") == 0), but still document
the such behaviors like regular operation ("[returns] %FALSE if @ptype
or @pitem was invalid"). Don't assert against the function arguments.
Also, if you first set the user to "fo:o", then
nm_setting_connection_add_permission() would accept it -- only at
a later phase, the property setter would assert against such values.
Also, the function would return %FALSE both if the input value was
invalid (an error) and if the value already existed. I think the
function should not treat a duplicate entry like a badly formatted
input.
Now the function does much less asserting of the arguments, but will
return %FALSE only if the values are invalid. And it will silently ignore
duplicate entries.
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/636
Run:
./contrib/scripts/nm-code-format.sh -i
./contrib/scripts/nm-code-format.sh -i
Yes, it needs to run twice because the first run doesn't yet produce the
final result.
Signed-off-by: Antonio Cardace <acardace@redhat.com>
This makes the macro more function like. Also, taking a pointer
makes it a bit clearer that this possibly changes the value.
Of course, it's not a big difference to before, but this
form seems slightly preferable to me.
The 'clsact' qdisc is similar to 'ingress' but supports both ingress
and egress [1]. It uses the same handle as 'ingress' and has two child
classes :fff2 (ingress) and :fff3 (egress) on which filters can be
attached.
With clsact, for example, it becomes possible to do port mirroring
with a single qdisc:
nmcli connection modify mirror +tc.qdisc "clsact"
nmcli connection modify mirror +tc.tfilter
"parent ffff:fff3 matchall action mirred egress mirror dev dummy1"
nmcli connection modify mirror +tc.tfilter
"parent ffff:fff2 matchall action mirred egress mirror dev dummy1"
instead of two (ingress + i.e. prio). We don't support yet the
symbolic names 'ingress' and 'egress' for :fff2 and :fff3 in the
filter.
See-also: https://bugzilla.redhat.com/show_bug.cgi?id=1436535
[1] https://lwn.net/Articles/671458/
- assert that WITH_JANSSON and JANSSON_SONAME are defined consistently.
This check ensures that we can check at compile time that nm_json_vt()
will always fail (because JANSSON_SONAME) is undefined.
That is interesting, because this means you can do a compile time
for !WITH_JANSSON, and know if nm_json_vt() will *never* succeed.
With that, we could let the linker know when the code is unused
and remove all uses of nm_json_vt(), without using the traditional
conditional compilation with "#if WITH_JANSSON". But of course, we
currently don't do this micro optimization to remove defunct code.
- drop the "mode" helper variable and pass the flags directly to
dlopen().
They serve a similar purpose.
Previously, nm-json-aux.h contained the virtual function table for accessing
the dynamically loaded libjansson. But there is no reason why our own
helper functions from nm-json.h cannot be there too.
We anyway load libjansson with dlopen(), and already before it could
happen that libjansson is not available. In that case, we would not
crash, but simply proceed without json validation.
Since libnm-core no longer uses libjansson directly, but only via
"nm-glib-aux/nm-json.h", we can just always compile with that, and use
it at runtime. That means, libjansson is not a build dependency for
libnm anymore, so we don't need a compile time check.
Note that if you build without libjansson, then JANSSON_SONAME is
undefined, and loading it will still fail at runtime. So, even if
we now always build with all our code enabled, it only works if you
actually build with libjansson. Still, it's simpler to drop the
conditional build, as the only benefit is a (minimally) smaller
build.
- mark global variables as const. This allows the linker to
mark the variable as read only.
- for nm_utils_wifi_[25]ghz_freqs(), don't generate a list based
on bg_table/a_table. Instead, keep static array of frequencies.
Since we have unit tests that check the consistency, this has
little maintenance effort.
- add unit tests
We want to parse "/proc/cmdline". That is space separated with support
for quoting and escaping. Our implementation becomes part of stable
behavior, and we should interpret the kernel command line the same way
as the system does. That means, our implementation should match
systemd's.
This does not match kernel behavior. You seem to be able to configure
multicast_snooping=auto,enabled with multicast_snooping off just fine.
Possibly this constrained was inspired by `ip link`, which says:
mcast_router MULTICAST_ROUTER - set bridge's multicast router if IGMP
snooping is enabled.
But kernel doesn't enforce this:
ip link delete br0 2>/dev/null; \
ip link add br0 type bridge mcast_router 1 mcast_snooping 0; \
grep ^ /sys/devices/virtual/net/br0/bridge/{multicast_router,multicast_snooping}
gives:
/sys/devices/virtual/net/br0/bridge/multicast_router:1
/sys/devices/virtual/net/br0/bridge/multicast_snooping:0
We probably should not implement additional constrains on top of what
kernel does, if the conditions are that obscure.
Fixes: e01d3b4c2b ('nm-setting-bridge: add 'multicast-router' bridge option')
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.
UBSan marks these:
libnm-core/tests/test-setting.c:2146:2: runtime error: left shift of 65521 by 16 places cannot be represented in type 'int'
#0 0x561739bed935 in test_tc_config_qdisc libnm-core/tests/test-setting.c:2146
By passing as length of the MAC addresses -1 for both arguments, one
could get through to compare empty strings, NULL, and addresses longer
than the maximum. Such addresses are not valid, and they should never
compare equal (not even to themselves).
This is a change in behavior of public API, but it never made sense to
claim two addresses are equal, when they are not even valid addresses.
Also, avoid undefined behavior with "NULL, -1, NULL, -1" arguments,
where we would call memcmp() with zero length and NULL arguments.
UBSan flags that too.
When parsing user input if is often convenient to allow stripping whitespace.
Especially with escaped strings, the user could still escape the whitespace,
if the space should be taken literally.
Add support for that to nm_utils_buf_utf8safe_unescape().
Note that this is not the same as calling g_strstrip() before/after
unescape. That is, because nm_utils_buf_utf8safe_unescape() correctly
preserves escaped whitespace. If you call g_strstrip() before/after
the unescape, you don't know whether the whitespace is escaped.