Commit Graph

355 Commits

Author SHA1 Message Date
Thomas Haller
02a0967520 libnm: fix setting error for nm_connection_update_secrets()
By convention, a function that indicates failure *MUST* set
an error.

Also, an error can only be set once.
2019-06-26 12:26:11 +02:00
Thomas Haller
87a73df959 all: drop empty first line from sources
git ls-files -z -- ':(exclude)src/settings/plugins/keyfile/tests/keyfiles' | xargs -0 -n1 sed -i '1 { /^$/d }'
2019-06-11 10:15:06 +02:00
Thomas Haller
c0e075c902 all: drop emacs file variables from source files
We no longer add these. If you use Emacs, configure it yourself.

Also, due to our "smart-tab" usage the editor anyway does a subpar
job handling our tabs. However, on the upside every user can choose
whatever tab-width he/she prefers. If "smart-tabs" are used properly
(like we do), every tab-width will work.

No manual changes, just ran commands:

    F=($(git grep -l -e '-\*-'))
    sed '1 { /\/\* *-\*-  *[mM]ode.*\*\/$/d }'     -i "${F[@]}"
    sed '1,4 { /^\(#\|--\|dnl\) *-\*- [mM]ode/d }' -i "${F[@]}"

Check remaining lines with:

    git grep -e '-\*-'

The ultimate purpose of this is to cleanup our files and eventually use
SPDX license identifiers. For that, first get rid of the boilerplate lines.
2019-06-11 10:04:00 +02:00
Thomas Haller
d7932ee5f1 tests/trivial: rename nmtst_get_rand_int() to nmtst_get_rand_uint32()
nmtst_get_rand_int() was originally named that way, because it
calls g_rand_int(). But I think if a function returns an uint32, it
should also be named that way.

Rename.
2019-06-11 08:25:10 +02:00
Thomas Haller
fac6aea730 libnm/tests: fix team tests with "--enable-json-validation=no" 2019-06-11 08:10:03 +02:00
Thomas Haller
23b1f8234d libnm/team: fix handling default values and stricter validate team config
For each artifical team property we need to track whether it was
explicitly set (i.e., present in JSON/GVariant or set by the user
via NMSettingTeam/NMSettingTeamPort API).

 --

As a plus, libnm is now no longer concerned with the underling default values
that teamd uses. For example, the effective default value for "notify_peers.count"
depends on the selected runner. But libnm does not need to care, it only cares
wheher the property is set in JSON or not. This also means that the default (e.g. as
interesting to `nmcli -o con show $PROFILE`) is independent from other properties
(like the runner).

Also change the default value for the GObject properties of
NMSettingTeam and NMSettingTeamPort to indicate the "unset" value.
For most properties, the default value is a special value that is
not a valid configuration itself.
For some properties the default value is itself a valid value, namely,
"runner.active", "runner.fast_rate", "port.sticky" and "port.prio".

As far as NMTeamSetting is concerned, it distinguishes between unset
value and set value (including the default value). That means,
when it parses a JSON or GVariant, it will remember whether the property
was present or not.

When using API of NMSettingTeam/NMSettingTeamPort to set a property to the
default value, it marks the property as unset. For example, setting
NM_SETTING_TEAM_RUNNER_ACTIVE to TRUE (the default), means that the
value will not be serialized to JSON/GVariant. For the above 4
properties (where the default value is itself a valid value) this is a
limitation of libnm API, as it does not allow to explicitly set
'"runner": { "active": true }'. See SET_FIELD_MODE_SET_UNLESS_DEFAULT,

Note that changing the default value for properties of NMSetting is problematic,
because it changes behavior for how settings are parsed from keyfile/GVariant.
For team settings that's not the case, because if a JSON "config" is
present, all other properties are ignore. Also, we serialize properties
to JSON/GVariant depending on whether it's marked as present, and not
whether the value is set to the default (_nm_team_settings_property_to_dbus()).

 --

While at it, sticter validate the settings. Note that if a setting is
initialized from JSON, the strict validation is not not performed. That
means, such a setting will always validate, regardless whether the values
in JSON are invalid according to libnm. Only when using the extended
properties, strict validation is turned on.

Note that libnm serializes the properties to GVariant both as JSON "config"
and extended properties. Since when parsing a setting from GVariant will
prefer the "config" (if present), in most cases also validation is
performed.

Likewise, settings plugins (keyfile, ifcfg-rh) only persist the JSON
config to disk. When loading a setting from file, strict validation is
also not performed.

The stricter validation only happens if as last operation one of the
artificial properties was set, or if the setting was created from a
GVariant that has no "config" field.

 --

This is a (another) change in behavior.
2019-06-04 15:48:15 +02:00
Thomas Haller
efe602af2a libnm/team: reorder fields in JSON output for team link watcher
The order of the fields in the JSON object does not really matter.

Note that with the recent rework the order changed. Before it was
arbitrarily, now it still is arbitrary.

Reorder again, to follow the same order as `man teamd.conf`.
2019-06-04 15:48:15 +02:00
Thomas Haller
56f45d7ba3 libnm/team: add space in JSON output for link watcher
Generate the following:

 { "runner": { "sys_prio": 10 }, "link_watch": { "name": "ethtool" } }

instead of:

 { "runner": { "sys_prio": 10 }, "link_watch": { "name": "ethtool"} }
2019-06-04 15:46:21 +02:00
Thomas Haller
13f6f3a410 libnm: rework team handling of JSON config
Completely refactor the team/JSON handling in libnm's NMSettingTeam and
NMSettingTeamPort.

- team handling was added as rh#1398925. The goal is to have a more
  convenient way to set properties than constructing JSON. This requires
  libnm to implement the hard task of parsing JSON (and exposing well-understood
  properties) and generating JSON (based on these "artificial" properties).
  But not only libnm. In particular nmcli and the D-Bus API must make this
  "simpler" API accessible.

- since NMSettingTeam and NMSettingTeamPort are conceptually the same,
  add "libnm-core/nm-team-utils.h" and NMTeamSetting that tries to
  handle the similar code side-by-sdie.
  The setting classes now just delegate for everything to NMTeamSetting.

- Previously, there was a very fuzzy understanding of the provided
  JSON config. Tighten that up, when setting a JSON config it
  regenerates/parses all other properties and tries to make the
  best of it. When modifying any abstraction property, the entire
  JSON config gets regenerated. In particular, don't try to merge
  existing JSON config with the new fields. If the user uses the
  abstraction API, then the entire JSON gets replaced.

  For example note that nm_setting_team_add_link_watcher() would not
  be reflected in the JSON config (a bug). That only accidentally worked
  because client would serializing the changed link watcher to
  GVariant/D-Bus, then NetworkManager would set it via g_object_set(),
  which would renerate the JSON, and finally persist it to disk. But
  as far as libnm is concerned, nm_setting_team_add_link_watcher() would
  bring the settings instance in an inconsistent state where JSON and
  the link watcher property disagree. Setting any property must
  immediately update both the JSON and the abstraction API.

- when constucting a team setting from D-Bus, we would previously parse
  both "config" and abstraction properties. That is wrong. Since our
  settings plugins only support JSON, all information must be present
  in the JSON config anyway. So, when "config" is present, only the JSON
  must be parsed. In the best case, the other information is redudant and
  contributes nothing. In the worse case, they information differs
  (which might happen if the client version differs from the server
  version). As the settings plugin only supports JSON, it's wrong to
  consider redundant, differing information from D-Bus.

- we now only convert string to JSON or back when needed. Previously,
  setting a property resulted in parsing several JSON multiple times
  (per property). All operations should now scale well and be reasonably
  efficient.

- also the property-changed signals are now handled correctly. Since
  NMTeamSetting knows the current state of all attributes, it can emit
  the exact property changed signals for what changed.

- we no longer use libjansson to generate the JSON. JSON is supposed
  to be a machine readable exchange format, hence a major goal is
  to be easily handled by applications. While parsing JSON is not so
  trivial, writing a well-known set of values to JSON is.
  The advantage is that when you build libnm without libjansson support,
  then we still can convert the artificial properties to JSON.

- Requiring libjansson in libnm is a burden, because most of the time
  it is not needed (as most users don't create team configurations). With
  this change we only require it to parse the team settings (no longer to
  write them). It should be reasonably simple to use a more minimalistic
  JSON parser that is sufficient for us, so that we can get rid of the
  libjansson dependency (for libnm). This also avoids the pain that we have
  due to the symbol collision of libjansson and libjson-glib.

https://bugzilla.redhat.com/show_bug.cgi?id=1691619
2019-05-23 18:09:49 +02:00
Thomas Haller
35c92cf582 libnm/tests: mark team tests as skipped without JSON validation
We should not just disable tests with an #if.

Instead, mark them as skipped. This way, we still compile them, and we
even run them (showing a message why they are skipped).
2019-05-23 18:09:49 +02:00
Thomas Haller
a178fbac26 libnm/tests: add tests for modifying team setting 2019-05-23 18:09:49 +02:00
Thomas Haller
49dbdae00a libnm/tests: check for identical team config in _team_config_equal_check() 2019-05-23 18:09:49 +02:00
Thomas Haller
9b0dee8e9c libnm/tests: cleanup tests 2019-05-23 18:09:49 +02:00
Thomas Haller
cc9f071676 libnm: cleanup _nm_utils_parse_tc_handle()
- g_ascii_strtoll() accepts leading spaces, but it leaves
  the end pointer at the first space after the digit. That means,
  we accepted "1: 0" but not "1 :0". We should either consistently
  accept spaces around the digits/colon or reject it.

- g_ascii_strtoll() accepts "\v" as a space (just like `man 3 isspace`
  comments that "\v" is a space in C and POSIX locale.
  For some reasons (unknown to me) g_ascii_isspace() does not treat
  "\v" as space. And neither does NM_ASCII_SPACES and
  nm_str_skip_leading_spaces().
  We should be consistent about what we consider spaces and what not.
  It's already odd to accept '\n' as spaces here, but well, lets do
  it for the sake of consistency (so that it matches with our
  understanding of ASCII spaces, albeit not POSIX's).

- don't use bogus error domains in "g_set_error (error, 1, 0, ..."
  That is a bug and we have NM_UTILS_ERROR exactly for error instances
  with unspecified domain and code.

- as before, accept a trailing ":" with omitted minor number.

- reject all unexpected characters. strtoll() accepts '+' / '-'
  and a "0x" prefix of the numbers (and leading POSIX spaces). Be
  strict here and only accepts NM_ASCII_SPACES, ':', and hexdigits.
  In particular, don't accept the "0x" prefix.

This parsing would be significantly simpler to implement, if we could
just strdup() the string, split the string at the colon delimiter and
use _nm_utils_ascii_str_to_int64() which gets leading/trailing spaces
right. But let's save the "overhead" of an additional alloc.
2019-05-07 20:58:17 +02:00
Thomas Haller
fac95d0062 libnm/tests: add test for _nm_utils_parse_tc_handle() 2019-05-07 20:58:17 +02:00
Thomas Haller
0a8f11639a libnm: refactor implementation of "ethernet.s390-options" property
- the previous implementation of nm_setting_wired_get_s390_option()
  returned the elements in an arbitrary order (because it just iterated
  idx times over the unsorted hash table).

- the API for "s390-options" suggests both accessing by index and by
  name. Storing the options in a hash-table is not optimal for lookup
  by index. It also requires us to sort the elements over and over
  again.
  Use instead a sorted array. Note that add/remove of course requires to
  move the elements (and has thus O(n)).

- "s390-options" are very seldomly set. We shouldn't pay the price in every
  NMSettingWired to allocate a GHashTable and deal with it.

- don't assert in nm_setting_wired_add_s390_option() and
  nm_setting_wired_remove_s390_option() that the key is valid.
  ifcfg-rh reader understandably does not want to implement additional
  logic to pre-validate the key, so any invalid keys would trigger an
  assertion failure. We have verify() for this purpose.
2019-04-25 09:22:51 +02:00
Thomas Haller
cf9b8d3bad libnm/keyfile: implement ethernet.s390-options in keyfile
Currently, nm_setting_wired_get_s390_option() returns the key
in an undefined order. Hence, the keyfile writer and the test
need to awkwardly sort the keys first. That will be solved better
in the next commit, when nm_setting_wired_get_s390_option() returns
the items sorted by key.
2019-04-25 09:07:55 +02:00
Thomas Haller
e7836cd151 build/meson: rename "nm_core_dep" to "libnm_core_dep"
The library is called "libnm_core". So the dependency should be called
"libnm_core_dep", like in all other cases.

(cherry picked from commit c27ad37c27)
2019-04-18 20:13:49 +02:00
Thomas Haller
284ac92eee shared: build helper "libnm-libnm-core-{intern|aux}.la" library for libnm-core
"libnm-core" implements common functionality for "NetworkManager" and
"libnm".

Note that clients like "nmcli" cannot access the internal API provided
by "libnm-core". So, if nmcli wants to do something that is also done by
"libnm-core", , "libnm", or "NetworkManager", the code would have to be
duplicated.

Instead, such code can be in "libnm-libnm-core-{intern|aux}.la".
Note that:

  0) "libnm-libnm-core-intern.la" is used by libnm-core itsself.
     On the other hand, "libnm-libnm-core-aux.la" is not used by
     libnm-core, but provides utilities on top of it.

  1) they both extend "libnm-core" with utlities that are not public
     API of libnm itself. Maybe part of the code should one day become
     public API of libnm. On the other hand, this is code for which
     we may not want to commit to a stable interface or which we
     don't want to provide as part of the API.

  2) "libnm-libnm-core-intern.la" is statically linked by "libnm-core"
     and thus directly available to "libnm" and "NetworkManager".
     On the other hand, "libnm-libnm-core-aux.la" may be used by "libnm"
     and "NetworkManager".
     Both libraries may be statically linked by libnm clients (like
     nmcli).

  3) it must only use glib, libnm-glib-aux.la, and the public API
     of libnm-core.
     This is important: it must not use "libnm-core/nm-core-internal.h"
     nor "libnm-core/nm-utils-private.h" so the static library is usable
     by nmcli which couldn't access these.

Note that "shared/nm-meta-setting.c" is an entirely different case,
because it behaves differently depending on whether linking against
"libnm-core" or the client programs. As such, this file must be compiled
twice.

(cherry picked from commit af07ed01c0)
2019-04-18 20:07:44 +02:00
Thomas Haller
d984b2ce4a shared: move most of "shared/nm-utils" to "shared/nm-glib-aux"
From the files under "shared/nm-utils" we build an internal library
that provides glib-based helper utilities.

Move the files of that basic library to a new subdirectory
"shared/nm-glib-aux" and rename the helper library "libnm-core-base.la"
to "libnm-glib-aux.la".

Reasons:

 - the name "utils" is overused in our code-base. Everything's an
   "utils". Give this thing a more distinct name.

 - there were additional files under "shared/nm-utils", which are not
   part of this internal library "libnm-utils-base.la". All the files
   that are part of this library should be together in the same
   directory, but files that are not, should not be there.

 - the new name should better convey what this library is and what is isn't:
   it's a set of utilities and helper functions that extend glib with
   funcitonality that we commonly need.

There are still some files left under "shared/nm-utils". They have less
a unifying propose to be in their own directory, so I leave them there
for now. But at least they are separate from "shared/nm-glib-aux",
which has a very clear purpose.

(cherry picked from commit 80db06f768)
2019-04-18 19:57:27 +02:00
Thomas Haller
0a6f21fb8d shared: split C-only helper "shared/nm-std-aux" utils out of "shared/nm-utils"
"shared/nm-utils" contains general purpose utility functions that only
depend on glib (and extend glib with some helper functions).

We will also add code that does not use glib, hence it would be good
if the part of "shared/nm-utils" that does not depend on glib, could be
used by these future projects.

Also, we use the term "utils" everywhere. While that covers the purpose
and content well, having everything called "nm-something-utils" is not
great. Instead, call this "nm-std-aux", inspired by "c-util/c-stdaux".

(cherry picked from commit b434b9ec07)
2019-04-18 19:17:23 +02:00
Thomas Haller
585077c5ba shared: remove unused _nm_utils_escape_plain()/_nm_utils_escape_spaces() API
... and the "unescape" variants.

This is replaced by nm_utils_escaped_tokens_split()
and nm_utils_escaped_tokens_escape*() API.

(cherry picked from commit 304eab8703)
2019-04-18 18:51:21 +02:00
Beniamino Galvani
da204257b1 all: support bridge vlan ranges
In some cases it is convenient to specify ranges of bridge vlans, as
already supported by iproute2 and natively by kernel. With this commit
it becomes possible to add a range in this way:

 nmcli connection modify eth0-slave +bridge-port.vlans "100-200 untagged"

vlan ranges can't be PVIDs because only one PVID vlan can exist.

https://bugzilla.redhat.com/show_bug.cgi?id=1652910
(cherry picked from commit 7093515777)
2019-04-18 09:53:18 +02:00
Thomas Haller
fd8b78dd6a libnm-core/tests: fix "-Werror=logical-not-parentheses" warning in _sock_addr_endpoint()
CC       libnm-core/tests/libnm_core_tests_test_general-test-general.o
  In file included from ../shared/nm-default.h:280:0,
                   from ../libnm-core/tests/test-general.c:24:
  ../libnm-core/tests/test-general.c: In function _sock_addr_endpoint:
  ../libnm-core/tests/test-general.c:5911:18: error: logical not is only applied to the left hand side of comparison [-Werror=logical-not-parentheses]
    g_assert (!host == (port == -1));
                    ^
  ../shared/nm-utils/nm-macros-internal.h:1793:7: note: in definition of macro __NM_G_BOOLEAN_EXPR_IMPL
     if (expr) \
         ^
  /usr/include/glib-2.0/glib/gmacros.h:376:43: note: in expansion of macro _G_BOOLEAN_EXPR
   #define G_LIKELY(expr) (__builtin_expect (_G_BOOLEAN_EXPR((expr)), 1))
                                             ^
  /usr/include/glib-2.0/glib/gtestutils.h:116:49: note: in expansion of macro G_LIKELY
                                                if G_LIKELY (expr) ; else \
                                                   ^
  ../libnm-core/tests/test-general.c:5911:2: note: in expansion of macro g_assert
    g_assert (!host == (port == -1));
    ^

Fixes: 713e879d76 ('libnm: add NMSockAddrEndpoint API')
(cherry picked from commit 1e8c08730f)
2019-04-18 09:48:40 +02:00
Thomas Haller
c0feedbaae shared/tests: add unit tests for new flags of nm_utils_strsplit_set_full()
(cherry picked from commit a7d1e14e6d)
2019-04-17 11:27:11 +02:00
Thomas Haller
2d1ae8dd97 libnm: use nm_utils_escaped_tokens_*() for parsing NMIPRoutingRule
Replace nm_utils_str_simpletokens_extract_next() by
nm_utils_escaped_tokens_split().

nm_utils_escaped_tokens_split() should become our first choice for
parsing and tokenizing.

Note that both nm_utils_str_simpletokens_extract_next() and
nm_utils_escaped_tokens_split() need to strdup the string once,
and tokenizing takes O(n). So, they are roughtly the same performance
wise. The only difference is, that as we iterate through the tokens,
we might abort early on error with nm_utils_str_simpletokens_extract_next()
and not parse the entire string. But that is a small benefit, since we
anyway always strdup() the string (being O(n) already).

Note that to-string will no longer escape ',' and ';'. This is a change
in behavior, of unreleased API. Also note, that escaping these is no
longer necessary, because nmcli soon will also use nm_utils_escaped_tokens_*().

Another change in behavior is that nm_utils_str_simpletokens_extract_next()
treated invalid escape sequences (backslashes followed by an arbitrary
character), buy stripping the backslash. nm_utils_escaped_tokens_*()
leaves such backslashes as is, and only honors them if they are followed
by a whitespace (the delimiter) or another backslash. The disadvantage
of the new approach is that backslashes are treated differently
depending on the following character. The benefit is, that most
backslashes can now be written verbatim, not requiring them to escape
them with a double-backslash.

Yes, there is a problem with these nested escape schemes:

  - the caller may already need to escape backslash in shell.

  - then nmcli will use backslash escaping to split the rules at ','.

  - then nm_ip_routing_rule_from_string() will honor backslash escaping
    for spaces.

  - then iifname and oifname use backslash escaping for nm_utils_buf_utf8safe_escape()
    to express non-UTF-8 characters (because interface names are not
    necessarily UTF-8).

This is only redeamed because escaping is really only necessary for very
unusual cases, if you want to embed a backslash, a space, a comma, or a
non-UTF-8 character. But if you have to, now you will be able to express
that.

The other upside of these layers of escaping is that they become all
indendent from each other:

  - shell can accept quoted/escaped arguments and will unescape them.

  - nmcli can do the tokenizing for ',' (and escape the content
    unconditionally when converting to string).

  - nm_ip_routing_rule_from_string() can do its tokenizing without
    special consideration of utf8safe escaping.

  - NMIPRoutingRule takes iifname/oifname as-is and is not concerned
    about nm_utils_buf_utf8safe_escape(). However, before configuring
    the rule in kernel, this utf8safe escape will be unescaped to get
    the interface name (which is non-UTF8 binary).

(cherry picked from commit b6d0be2d3b)
2019-04-17 11:27:11 +02:00
Beniamino Galvani
834dfd72c5 libnm-core: fix wrong memory access in tests
==16725==ERROR: AddressSanitizer: global-buffer-overflow on address 0x0000005a159f at pc 0x00000046fc1b bp 0x7fff6038f900 sp 0x7fff6038f8f0
READ of size 1 at 0x0000005a159f thread T0
    #0 0x46fc1a in _do_test_unescape_spaces libnm-core/tests/test-general.c:7791
    #1 0x46fe5b in test_nm_utils_unescape_spaces libnm-core/tests/test-general.c:7810
    #2 0x7f4ac5fe7fc9 in test_case_run gtestutils.c:2318
    #3 0x7f4ac5fe7fc9 in g_test_run_suite_internal gtestutils.c:2403
    #4 0x7f4ac5fe7e83 in g_test_run_suite_internal gtestutils.c:2415
    #5 0x7f4ac5fe7e83 in g_test_run_suite_internal gtestutils.c:2415
    #6 0x7f4ac5fe8281 in g_test_run_suite gtestutils.c:2490
    #7 0x7f4ac5fe82a4 in g_test_run (/lib64/libglib-2.0.so.0+0x772a4)
    #8 0x48240d in main libnm-core/tests/test-general.c:7994
    #9 0x7f4ac5dc9412 in __libc_start_main (/lib64/libc.so.6+0x24412)
    #10 0x423ffd in _start (/home/bgalvani/work/NetworkManager/libnm-core/tests/test-general+0x423ffd)

0x0000005a159f is located 49 bytes to the right of global variable '*.LC370' defined in 'libnm-core/tests/test-general.c' (0x5a1560) of size 14
  '*.LC370' is ascii string 'nick-5, green'
0x0000005a159f is located 1 bytes to the left of global variable '*.LC371' defined in 'libnm-core/tests/test-general.c' (0x5a15a0) of size 1
  '*.LC371' is ascii string ''
SUMMARY: AddressSanitizer: global-buffer-overflow libnm-core/tests/test-general.c:7791 in _do_test_unescape_spaces
2019-04-12 11:19:58 +02:00
Thomas Haller
5c1f93943e shared: add NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY flag for nm_utils_strsplit_set_full()
Previously, nm_utils_strsplit_set_full() would always remove empty
tokens. Add a flag NM_UTILS_STRSPLIT_SET_FLAGS_PRESERVE_EMPTY to avoid
that.

This makes nm_utils_strsplit_set_full() return the same result as
g_strsplit_set() and a direct replacement for it -- except for "",
where we return %NULL.
2019-04-10 15:05:57 +02:00
Thomas Haller
84f2037648 shared: add flags argument to nm_utils_strsplit_set()
It will be useful to extend nm_utils_strsplit_set() with various
flavors and subtly different behaviors. Add a flags argument to
support these.
2019-04-10 15:05:57 +02:00
Thomas Haller
b25cf61a33 libnm/infiniband: lift restriction of MTU to 2044 for IPoIB in "datagram" mode
Traditionally, the MTU in "datagram" transport mode was restricted to
2044. That is no longer the case, relax that.

In fact, choose a very large maximum and don't differenciate between
"connected" mode (they now both use now 65520). This is only the
limitation of the connection profile. Whether setting such large MTUs
actually works must be determined when activating the profile.

Initscripts "ifup-ib" from rdma-core package originally had a limit of 2044.
This was raised to 4092 in rh#1186498. It is suggested to raise it further
in bug rh#1647541.

In general, kernel often does not allow setting large MTUs. And even if it
allows it, it may not work because it also requires the entire network to
be configured accordingly. But that means, it is generally not helpful to
limit the MTU in the connection profile too strictly. Just allow large
MTUs, we need to see at activation time whether the configuration works.

Note also that all other setting types don't validate the range for MTU at
all.

Related: https://bugzilla.redhat.com/show_bug.cgi?id=1186498
Related: https://bugzilla.redhat.com/show_bug.cgi?id=1593334
         (rdma-core: raise limit from 2044 to 4092 in ifup-ib)

Related: https://bugzilla.redhat.com/show_bug.cgi?id=1647541
         (rdma-core: raise limit beyond 4092 in ifup-ib)

Related: https://bugzilla.redhat.com/show_bug.cgi?id=1532638#c4
         (rdma-core: MTU related discussion)

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1534869
       (NetworkManager bug about this topic, but with lots of unrelated
        discussion. See in particular #c16)

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1653494
2019-04-05 16:27:17 +02:00
Beniamino Galvani
23d8a4f230 libnm-core: fix memory leak in setting test
Fixes: 7fb23b0a62 ('libnm: add NMIPRoutingRule API')
2019-03-31 12:03:31 +02:00
Thomas Haller
6e6d1e070c libnm: add API to NMSettingIPConfig for routing rules 2019-03-27 16:23:30 +01:00
Thomas Haller
7fb23b0a62 libnm: add NMIPRoutingRule API
Add NMIPRoutingRule API with a few basic rule properties. More
properties will be added later as we want to support them.

Also, add to/from functions for string/GVariant representations.
These will be needed to persist/load/exchange rules.

The to-string format follows the `ip rule add` syntax, with the aim
to be partially compatible. Full compatibility is not possible though,
for various reasons (see code comment).
2019-03-27 16:23:30 +01:00
Beniamino Galvani
c66d17d4fc keyfile: support bridge vlans 2019-03-26 17:19:39 +01:00
Beniamino Galvani
cf71860183 libnm-core: add bridge vlan conversion utils 2019-03-26 17:18:29 +01:00
Thomas Haller
5b8305c27c shared: add NM_ASCII_SPACES macro 2019-03-25 09:12:33 +01:00
Thomas Haller
e3fa570c1b shared: add "strip" argument to _nm_utils_unescape_spaces()
It's usually not necessary, because _nm_utils_unescape_spaces()
gets called after nm_utils_strsplit_set(), which already removes
the non-escaped spaces.

Still, for completeness, this should be here. Also, because with
this the function is useful for individual options (not delimiter
separate list values), to support automatically dropping leading or
trailing whitespace, but also support escaping them.
2019-03-25 09:12:33 +01:00
Thomas Haller
395738900f libnm: don't use strlen() for checking for non-empty string
It's well understood that these are NUL terminated strings.
We don't need strlen() to check that the strings aren't
empty.
2019-03-25 09:12:32 +01:00
Thomas Haller
f617d5e8b4 libnm: change nm_wireguard_peer_set_endpoint() API to allow validation
This is an API break since 1.16-rc1.

Similar to previous commit.

(cherry picked from commit 8ae9aa2428)
2019-03-07 22:22:39 +01:00
Thomas Haller
6452d2d0e5 libnm: change nm_wireguard_peer_set_public_key() API to allow validation
This is an API break since 1.16-rc1.

Similar to previous commit.

(cherry picked from commit 7962653918)
2019-03-07 22:22:39 +01:00
Thomas Haller
7682826229 libnm: change nm_wireguard_peer_set_preshared_key() API to allow validation
This is an API break since 1.16-rc1.

The functions like _nm_utils_wireguard_decode_key() are internal API
and not accessible to a libnm user. Maybe this should be public API,
but for now it is not.

That makes it cumbersome for a client to validate the setting. The client
could only reimplement the validation (bad) or go ahead and set invalid
value.

When setting an invalid value, the user can afterwards detect it via
nm_wireguard_peer_is_valid(), but at that point, it's not clear which
exact property is invalid.

First I wanted to keep the API conservative and not promissing too much.
For example, not promising to do any validation when setting the key.
However, libnm indeed validates the key at the time of setting it
instead of doing lazy validation later. This makes sense, so we can
keep this promise and just expose the validation result to the caller.

Another downside of this is that the API just got more complicated.
But it not provides a validation API, that we previously did not have.

(cherry picked from commit d7bc1750c1)
2019-03-07 22:22:39 +01:00
Thomas Haller
b1f6d53bc4 build/meson: increase timeouts for some tests
The defaults for test timeouts in meson is 30 seconds. That is not long
enough when running

  $ NMTST_USE_VALGRIND=1 ninja -C build test

Note that meson supports --timeout-multiplier, and automatically
increases the timeout when running under valgrind. However, meson
does not understand that we are running tests under valgrind via
NMTST_USE_VALGRIND=1 environment variable.

Timeouts are really not expected to be reached and are a mean of last
resort. Hence, increasing the timeout to a large value is likely to
have no effect or to fix test failures where the timeout was too rigid.
It's unlikely that the test indeed hangs and the increase of timeout
causes a unnecessary increase of waittime before aborting.
2019-02-23 07:20:49 +01:00
Thomas Haller
395a78618b libnm/tests: add tests for creating wireguard connection profiles 2019-02-22 11:00:11 +01:00
Thomas Haller
713e879d76 libnm: add NMSockAddrEndpoint API
NMSockAddrEndpoint is an immutable structure that contains the endpoint
string of a service. It also includes the (naive) parsing of the host and
port/service parts.

This will be used for the endpoint of WireGuard's peers. But since endpoints
are not something specific to WireGuard, give it a general name (and
purpose) independent from WireGuard.

Essentially, this structure takes a string in a manner that libnm
understands, and uses it for node and service arguments for
getaddrinfo().

NMSockAddrEndpoint allows to have endpoints that are not parsable into
a host and port part. That is useful because our settings need to be
able to hold invalid values. That is for forward compatibility (server
sends a new endpoint format) and for better error handling (have
invalid settings that can be constructed without loss, but fail later
during the NMSetting:verify() step).
2019-02-14 08:00:29 +01:00
Thomas Haller
a3370af3a8 all: drop unnecessary includes of <errno.h> and <string.h>
"nm-macros-interal.h" already includes <errno.h> and <string.h>.
No need to include it everywhere else too.
2019-02-12 08:50:28 +01:00
Thomas Haller
814bcf5575 libnm: avoid "-Wmissing-braces" warning for intializing NMUuid 2019-02-08 20:14:50 +01:00
Thomas Haller
290dbf1170 libnm/tests: add tests for comparing settings with different secret-flags
The flags NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS and
NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS act on the secret flags
to decide whether to ignore a secret.

But there was not test how this behaved, if the two settings had
differing flags.
2019-01-11 11:48:47 +01:00
Thomas Haller
4d1b8edb73 libnm/tests: compare D-Bus and keyfile serialization in roundtrip-conversion test 2019-01-08 16:16:18 +01:00
Thomas Haller
7771473f46 libnm,core: add _nm_connection_aggregate() to replace nm_connection_for_each_setting_value()
We should no longer use nm_connection_for_each_setting_value() and
nm_setting_for_each_value(). It's fundamentally broken as it does
not work with properties that are not backed by a GObject property
and it cannot be fixed because it is public API.

Add an internal function _nm_connection_aggregate() to replace it.

Compare the implementation of the aggregation functionality inside
libnm with the previous two checks for secret-flags that it replaces:

- previous approach broke abstraction and require detailed knowledge of
  secret flags. Meaning, they must special case NMSettingVpn and
  GObject-property based secrets.
  If we implement a new way for implementing secrets (like we will need
  for WireGuard), then this the new way should only affect libnm-core,
  not require changes elsewhere.

- it's very inefficient to itereate over all settings. It involves
  cloning and sorting the list of settings, and retrieve and clone all
  GObject properties. Only to look at secret properties alone.

_nm_connection_aggregate() is supposed to be more flexible then just
the two new aggregate types that perform a "find-any" search. The
@arg argument and boolean return value can suffice to implement
different aggregation types in the future.

Also fixes the check of NMAgentManager for secret flags for VPNs
(NM_CONNECTION_AGGREGATE_ANY_SYSTEM_SECRET_FLAGS). A secret for VPNs
is a property that either has a secret or a secret-flag. The previous
implementation would only look at present secrets and
check their flags. It wouldn't check secret-flags that are
NM_SETTING_SECRET_FLAG_NONE, but have no secret.
2019-01-07 10:54:28 +01:00
Thomas Haller
75e4284781 keyfile: rework handling of GObject properties from keyfile
- previously, writer would use nm_keyfile_plugin_kf_set_integer() for
  G_TYPE_UINT types.
  That means, values larger than G_MAXINT would be stored as negative
  values. On the other hand, the reader would always reject negative
  values.
  Fix that, by parsing the integer ourself.
  Note that we still reject the old (negative) values and there is no
  compatibility for accepting such values. They were not accepted by
  reader in the past and so they are still rejected.
  This affects for example ethernet.mtu setting (arguably, the MTU
  is usually set to small values where the issue was not apparent).
  This is also covered by a test.

- no longer use nm_keyfile_plugin_kf_set_integer().
  nm_keyfile_plugin_kf_set_integer() calls g_key_file_get_integer(), which
  uses g_key_file_parse_integer_as_value(). That one has the odd
  behavior of accepting "<number><whitespace><bogus>" as valid. Note how that
  differs from g_key_file_parse_value_as_double() which rejects trailing data.
  Implement the parsing ourself. There are some changes here:

  - g_key_file_parse_value_as_integer() uses strtol() with base 10.
    We no longer require a certain the base, so '0x' hex values are allowed
    now as well.

  - bogus suffixes are now rejected but were accepted by g_key_file_parse_value_as_integer().
    We however still accept leading and trailing whitespace, as before.

- use nm_g_object_set_property*(). g_object_set() asserts that the value
  is in range. We cannot pass invalid values without checking that they
  are valid.

- emit warnings when values cannot be parsed. Previously they would
  have been silently ignored or fail an assertion during g_object_set().

- don't use "helpers" like nm_keyfile_plugin_kf_set_uint64(). These
  merely call GKeyFile's setters (taking care of aliases). The setters
  of GKeyFile don't do anything miraculously, they merely call
  g_key_file_set_value() with the string that one would expect.
  Convert the numbers/boolean ourselfs. For one, we don't require
  a heap allocation to convert a number to string. Also, there is
  no point in leaving this GKeyFile API, because even if GKeyFile
  day would change, we still must continue to support the present
  format, as that is what users have on disk. So, even if a new
  way would be implemented by GKeyFile, the current way must forever
  be accepted too. Hence, we don't need this abstraction.
2019-01-07 10:41:00 +01:00